Xác định biến toàn cục trong hàm JavaScript


511

Có thể định nghĩa một biến toàn cục trong hàm JavaScript không?

Tôi muốn sử dụng trailimagebiến (khai báo trong makeObjhàm) trong các hàm khác.

<html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title></title>
        <script type="text/javascript">
            var offsetfrommouse = [10, -20];
            var displayduration = 0;
            var obj_selected = 0;
            function makeObj(address) {
                **var trailimage = [address, 50, 50];**
                document.write('<img id="trailimageid" src="' + trailimage[0] + '" border="0"  style=" position: absolute; visibility:visible; left: 0px; top: 0px; width: ' + trailimage[1] + 'px; height: ' + trailimage[2] + 'px">');
                obj_selected = 1;
            }

            function truebody() {
                return (!window.opera && document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
            }
            function hidetrail() {
                var x = document.getElementById("trailimageid").style;
                x.visibility = "hidden";
                document.onmousemove = "";
            }
            function followmouse(e) {
                var xcoord = offsetfrommouse[0];
                var ycoord = offsetfrommouse[1];
                var x = document.getElementById("trailimageid").style;
                if (typeof e != "undefined") {
                    xcoord += e.pageX;
                    ycoord += e.pageY;
                }
                else if (typeof window.event != "undefined") {
                    xcoord += truebody().scrollLeft + event.clientX;
                    ycoord += truebody().scrollTop + event.clientY;
                }
                var docwidth = 1395;
                var docheight = 676;
                if (xcoord + trailimage[1] + 3 > docwidth || ycoord + trailimage[2] > docheight) {
                    x.display = "none";
                    alert("inja");
                }
                else
                    x.display = "";
                x.left = xcoord + "px";
                x.top = ycoord + "px";
            }

            if (obj_selected = 1) {
                alert("obj_selected = true");
                document.onmousemove = followmouse;
                if (displayduration > 0)
                    setTimeout("hidetrail()", displayduration * 1000);
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <img alt="" id="house" src="Pictures/sides/right.gif" style="z-index: 1; left: 372px;
            top: 219px; position: absolute; height: 138px; width: 120px" onclick="javascript:makeObj('Pictures/sides/sides-not-clicked.gif');" />
        </form>
    </body>
</html>

19
để tuyên bố toàn cầu đơn giản là không sử dụng từ khóa "var"
Ibu

20
@Ibrahim: "để khai báo toàn cầu đơn giản là không sử dụng từ khóa" var "" Gak! Kinh dị ! ;-) Rất may, chế độ nghiêm ngặt không còn với các thế giới ngầm.
TJ Crowder

28
@Ibrahim Diallo - không sử dụng varkhông khai báo biến toàn cục. Hậu quả của việc gán giá trị cho biến không được khai báo là việc tạo một thuộc tính trên đối tượng toàn cục, điều này hoàn toàn khác với việc khai báo một biến.
RobG

1
Thông tin hữu ích trong câu trả lời này, quá stackoverflow.com/a/4862268/1356098 :)
Erenor Paz

Câu trả lời:


739

Có, như những người khác đã nói, bạn có thể sử dụng varở phạm vi toàn cầu (bên ngoài tất cả các hàm) để khai báo một biến toàn cục:

<script>
var yourGlobalVariable;
function foo() {
    // ...
}
</script>

Thay phiên, bạn có thể gán cho một tài sản trên window:

<script>
function foo() {
    window.yourGlobalVariable = ...;
}
</script>

... bởi vì trong các trình duyệt, tất cả các biến toàn cục biến toàn cục được khai báo varlà thuộc tính của windowđối tượng. (Trong đặc điểm kỹ thuật mới nhất, ECMAScript năm 2015, mới let, constclassbáo cáo tại phạm vi toàn cầu tạo globals mà không phải là thuộc tính của đối tượng toàn cầu, một khái niệm mới trong ES2015.)

(Cũng có sự kinh hoàng của các thế giới ngầm , nhưng đừng cố tình làm điều đó và cố hết sức để tránh làm điều đó một cách tình cờ, có lẽ bằng cách sử dụng ES5 "use strict".)

Tất cả những gì đã nói: Tôi sẽ tránh các biến toàn cục nếu bạn có thể (và bạn gần như chắc chắn có thể). Như tôi đã đề cập, cuối cùng chúng là tài sản của window, và windowđã có quá nhiều người đủ với tất cả các yếu tố với id(và nhiều người chỉ có một name) bị bỏ trong đó (và bất kể thông số kỹ thuật sắp tới nào, IE chỉ bỏ qua bất cứ thứ gì có nametrên đó ).

Thay vào đó, hãy bọc mã của bạn trong một hàm phạm vi và sử dụng các biến cục bộ cho hàm phạm vi đó và làm cho các hàm khác của bạn đóng trong nó:

<script>
(function() { // Begin scoping function
    var yourGlobalVariable; // Global to your code, invisible outside the scoping function
    function foo() {
        // ...
    }
})();         // End scoping function
</script>

98
+1 Khai báo rõ ràng nó ra cửa sổ là cách dễ đọc nhất.
Caspar Kleijne

8
Lưu ý rằng việc sử dụng windowsẽ không hoạt động trong Node. Thủ thuật đơn giản nhất ở đây là đặt: GLOBAL.window = GLOBAL;- như được giải thích trong câu hỏi liên quan này . Tất nhiên, nó không đẹp về mặt khái niệm. Tôi thích làm mọi thứ theo cách khác, vì vậy tôi có thể sử dụng GLOBALthay vì window.
Domi

4
@CasparKleijne, tôi không hiểu điều đó. Tại sao bạn lại gán nó trên cửa sổ khi bạn thực sự không có bằng chứng nào cho thấy đối tượng cửa sổ thực sự tồn tại. Bạn không biết gì về cách mã của bạn sẽ được sử dụng trong tương lai. Nó thậm chí có thể được sử dụng trong môi trường MongoDB hoặc rino thay vì nút của bạn. Và đối tượng cửa sổ cũng không thể nhìn thấy ngay cả trong trình duyệt nếu bạn sử dụng nhân viên web chẳng hạn. Điều này sẽ hoàn toàn giết chết tái sử dụng.
Gherman

4
window.yourGlobalVariable = ...;hoạt động như một lá bùa sau khi đọc 5 đến 6 câu hỏi trên trang web stack.
Ahmed Syed

6
@JacquesKoekemoer: Không có lý do gì để sử dụng evalở đó. Thay vào đó:window[dynamic_variable_name] = dynamic_variable_value;
TJ Crowder

19

CẬP NHẬT1: Nếu bạn đọc các bình luận, có một cuộc thảo luận thú vị xung quanh quy ước đặt tên cụ thể này.

CẬP NHẬT2: Có vẻ như vì câu trả lời của tôi đã được đăng nên quy ước đặt tên đã trở nên trang trọng hơn. Những người dạy, viết sách, vv nói về varkhai báo, và functionkhai báo.

CẬP NHẬT3: Đây là bài đăng wikipedia bổ sung hỗ trợ quan điểm của tôi: http://en.wikipedia.org/wiki/Declaration_(computer_programming)#Declarations_and_Def địnhs

... Và để trả lời câu hỏi chính. Biến KHAI THÁC trước chức năng của bạn. Điều này sẽ hoạt động và nó sẽ tuân thủ thông lệ tốt khi khai báo các biến của bạn ở đầu phạm vi :)


7
Nếu bạn muốn xác định các biến của mình ở nơi khác, hãy chắc chắn hiểu được cẩu là gì. Đây là một bài viết rất tốt đẹp về nó adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting . Chúc may mắn!
op1ekun

1
Đây không phải là ý nghĩa definitiondeclarationý nghĩa trong C. Dòng đầu tiên của bạn có thể là khai báo hoặc định nghĩa (tùy thuộc vào vị trí của nó); thứ hai chỉ là một nhiệm vụ. Một khai báo chỉ định cách giải thích của định danh (nghĩa myVarlà là một int); nếu khai báo cũng dự trữ lưu trữ, nó là một definition. Điều này không liên quan đến việc gõ; đó là một phần trong cách các đơn vị biên dịch hiểu các tham chiếu đến các đơn vị biên dịch khác.
EML

4
Ngay cả trong JS, var myVarđược gọi là khai báo (không cần phải gõ) và myVar = 10một bài tập . Tôi đã nghe thuật ngữ "định nghĩa" cho hợp chất ( var myVar = 10;).
Bergi

2
Điều này không giúp trả lời câu hỏi. Nó nên là một bình luận, không phải là một câu trả lời.
Diễn viên đóng thế

2
@Stuntddude có lẽ bạn đúng :( Tôi bắt đầu trả lời câu hỏi và sau đó quyết định chuyển hướng một chút, và đây là những gì chúng tôi có. Tuy nhiên, một số người vẫn thấy nó hữu ích vì vậy tôi đã để nó ở đây. Phản hồi!
op1ekun

15

Chỉ cần khai báo

var trialImage;

ở ngoài. Sau đó

function makeObj(address) {
    trialImage = [address, 50, 50];
..
..
}

Hi vọng điêu nay co ich.


12

Không, bạn không thể. Chỉ cần khai báo biến ngoài hàm. Bạn không phải khai báo nó cùng lúc với khi bạn gán giá trị:

var trailimage;

function makeObj(address) {
  trailimage = [address, 50, 50];

1
Lấy làm tiếc! "Có thể định nghĩa một biến toàn cục trong hàm JavaScript không?" - "Không, bạn không thể" không đúng, như câu trả lời đầu tiên cho thấy!
mustafa.0x

5
@ mustafa.0x: Bạn đang nhầm. Bạn không thể xác định một biến toàn cục bên trong một hàm. Bạn có thể ngầm định tạo một biến toàn cục hoặc tạo một thuộc tính cửa sổ bên trong một hàm, nhưng bạn không thể xác định một biến toàn cục bên trong một hàm.
Guffa

1
Liên quan đến JavaScript trong môi trường trình duyệt, một biến toàn cục và thuộc windowtính là đồng nghĩa. Dù bằng cách nào, sự khác biệt về ngữ nghĩa mà bạn đang thực hiện là rõ ràng, vì vậy tôi không ngại bỏ qua. Chỉnh sửa: không thể thay đổi phiếu bầu của tôi, xin lỗi!
mustafa.0x

2
nếu bạn không sử dụng nghiêm ngặt (nhưng tại sao bạn không sử dụng nghiêm ngặt?), bạn thực sự có thể khai báo và định nghĩa các vars toàn cầu bên trong một hàm bằng cách chống lại tất cả các thực tiễn tốt và chỉ không sử dụng var, đó là ý nghĩa của Guffa khi tạo ra (chẳng hạn như @DhruvPathak cũng chỉ ở đó).
cregox

11

Chỉ cần khai báo nó bên ngoài các hàm và gán các giá trị bên trong các hàm. Cái gì đó như:

<script type="text/javascript">
    var offsetfrommouse = [10, -20];
    var displayduration = 0;
    var obj_selected = 0;
    var trailimage = null ;  // GLOBAL VARIABLE
    function makeObj(address) {
        trailimage = [address, 50, 50];  //ASSIGN VALUE

Hoặc chỉ cần loại bỏ "var" khỏi tên biến của bạn bên trong hàm cũng làm cho nó toàn cục, nhưng tốt hơn là khai báo nó bên ngoài một lần để có mã sạch hơn. Điều này cũng sẽ làm việc:

var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;

function makeObj(address) {
    trailimage = [address, 50, 50];  //GLOBAL VARIABLE , ASSIGN VALUE

Tôi hy vọng ví dụ này giải thích thêm: http://jsfiddle.net/qCrGE/

var globalOne = 3;
testOne();

function testOne()
{
    globalOne += 2;
    alert("globalOne is : " + globalOne );
    globalOne += 1;
}

alert("outside globalOne is : " + globalOne);

testTwo();

function testTwo()
{
    globalTwo = 20;
    alert("globalTwo is " + globalTwo);
    globalTwo += 5;
}

alert("outside globalTwo is :" + globalTwo);

3

Nó rất đơn giản xác định biến trailimage bên ngoài hàm và đặt giá trị của nó trong hàm makeObj. Bây giờ bạn có thể truy cập giá trị của nó từ bất cứ đâu.

var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
var trailimage;
function makeObj(address) {
      trailimage = [address, 50, 50];
      ....
}

2
    var Global = 'Global';

    function LocalToGlobalVariable() {

    //This creates a local variable.

    var Local = '5';

    //Doing this makes the variable available for one session
    //(a page refresh - Its the session not local)

    sessionStorage.LocalToGlobalVar = Local;

    // It can be named anything as long as the sessionStorage references the local variable.
    // Otherwise it won't work
    //This refreshes the page to make the variable take effect instead of the last variable set.

    location.reload(false);
    };

    //This calls the variable outside of the function for whatever use you want.

    sessionStorage.LocalToGlobalVar;

Tôi nhận ra rằng có thể có rất nhiều lỗi cú pháp trong đó nhưng đó là ý tưởng chung ... Cảm ơn rất nhiều LayZee đã chỉ ra điều này ... Bạn có thể tìm thấy Lưu trữ cục bộ và phiên tại http: //www.w3schools. com / html / html5_webst Storage.asp . Tôi đã cần điều tương tự cho mã của tôi và đây là một ý tưởng thực sự tốt.


Cho đến nay, đây là câu trả lời duy nhất hoạt động, nhưng nó yêu cầu tải lại trang và location.reload(false);làm mới trang nhiều lần.
iyrin

1

Ví dụ cổ điển:

window.foo = 'bar';

Ví dụ hiện đại, an toàn theo thông lệ tốt nhất bằng cách sử dụng IIFE :

;(function (root) {
    'use strict'

    root.foo = 'bar';
)(this));

Ngày nay, cũng có tùy chọn sử dụng API WebStorage

localStorage.foo = 42;

hoặc là

sessionStorage.bar = 21;

Về mặt hiệu suất, tôi không chắc liệu nó có chậm hơn đáng kể so với việc lưu trữ các giá trị trong các biến hay không.

Hỗ trợ trình duyệt rộng rãi như đã nêu trên Tôi có thể sử dụng ...


localStorage và sessionStorage chỉ hoạt động cho các giá trị chuỗi.
HereToLearn_

Đúng vậy, @HereToLearn_, nhưng sau đó bạn có thể sử dụng localStorage.foo = JSON.stringify({ arbitrary: 'object', meaning: 42, awesome: true });var foo = JSON.decode(localStorage.foo);.
Lars Gyrup Brink Nielsen

Điều gì localStoragephải làm với các biến toàn cầu?
Michał Perłakowski

1
OP đang tìm kiếm giải pháp cho vấn đề này: "Tôi muốn sử dụng biến trailimage (được khai báo trong hàm makeObj) trong các chức năng khác." Ai nói rằng giải pháp phải liên quan đến các biến toàn cầu? Biến toàn cầu hiếm khi là một giải pháp tốt cho bất cứ điều gì.
Lars Gyrup Brink Nielsen

0

Vì vậy, bạn muốn các biến bên trong chức năng có sẵn bên ngoài chức năng? Tại sao không trả về kết quả của biến bên trong hàm? var x = function returnX { var x = 0; return x; }là ý tưởng ...

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
    <title></title>
    <script type="text/javascript">

        var offsetfrommouse = [10, -20];
        var displayduration = 0;
        var obj_selected = 0;

        function makeObj(address) {
            var trailimage = [address, 50, 50];
            document.write('<img id="trailimageid" src="' + trailimage[0] + '" border="0"  style=" position: absolute; visibility:visible; left: 0px; top: 0px; width: ' + trailimage[1] + 'px; height: ' + trailimage[2] + 'px">');
            obj_selected = 1;
            return trailimage;
        }

        function truebody() {
            return (!window.opera && document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
        }

        function hidetrail() {
            var x = document.getElementById("trailimageid").style;
            x.visibility = "hidden";
            document.onmousemove = "";
        }

        function followmouse(e) {
            var xcoord = offsetfrommouse[0];
            var ycoord = offsetfrommouse[1];
            var x = document.getElementById("trailimageid").style;
            if (typeof e != "undefined") {
                xcoord += e.pageX;
                ycoord += e.pageY;
            }

            else if (typeof window.event != "undefined") {
                xcoord += truebody().scrollLeft + event.clientX;
                ycoord += truebody().scrollTop + event.clientY;
            }
            var docwidth = 1395;
            var docheight = 676;
            if (xcoord + trailimage[1] + 3 > docwidth || ycoord + trailimage[2] > docheight) {
                x.display = "none";
                alert("inja");
            }
            else
                x.display = "";
            x.left = xcoord + "px";
            x.top = ycoord + "px";
        }

        if (obj_selected = 1) {
            alert("obj_selected = true");
            document.onmousemove = followmouse;
            if (displayduration > 0)
                setTimeout("hidetrail()", displayduration * 1000);
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <img alt="" id="house" src="Pictures/sides/right.gif" style="z-index: 1; left: 372px; top: 219px; position: absolute; height: 138px; width: 120px" onclick="javascript:makeObj('Pictures/sides/sides-not-clicked.gif');" />
    </form>
</body>
</html>

Tôi đã không kiểm tra điều này, nhưng nếu mã của bạn hoạt động trước thay đổi nhỏ đó, thì nó sẽ hoạt động.


-1

Đây là một mã mẫu có thể có ích.

  var Human = function(){
   name = "Shohanur Rahaman";  // global variable
   this.name = "Tuly"; // constructor variable 
   var age = 21;
 };

  var shohan = new Human();

 document.write(shohan.name+"<br>");
 document.write(name);
 document.write(age); // undefined cause its local variable 

Ở đây tôi tìm thấy một câu trả lời thoải mái như thế nào-lon-one-khai báo-một-toàn cầu biến trong JavaScript


Trong khi về mặt lý thuyết có thể trả lời câu hỏi, tốt hơn là nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo.
Rohit Gupta

-1

Đây là một phương pháp dễ dàng khác để làm cho biến có sẵn trong các hàm khác mà không phải sử dụng biến toàn cục:

function makeObj() {
  // var trailimage = 'test';
  makeObj.trailimage = 'test';
}
function someOtherFunction() {
  document.write(makeObj.trailimage);
}

makeObj();
someOtherFunction();


-2

nếu bạn đang tạo một hàm khởi động, bạn có thể xác định các hàm và biến toàn cục theo cách đó:

function(globalScope)
{
     //define something
     globalScope.something() { 
         alert("It works");
     };
}(window)

Bởi vì hàm được gọi trên toàn cầu với đối số này, đây là phạm vi toàn cầu ở đây. Vì vậy, một cái gì đó nên là một điều toàn cầu.


thisundefinedtrong chế độ nghiêm ngặt bên ngoài một chức năng và không nên được sử dụng để tham khảo các đối tượng toàn cầu.
Michał Perłakowski
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.