Cách khai báo một biến toàn cục trong tệp .js


86

Tôi cần một vài biến toàn cục mà tôi cần trong tất cả .jscác tệp.

Ví dụ: hãy xem xét 4 tệp sau:

  1. global.js
  2. js1.js
  3. js2.js
  4. js3.js

Có cách nào để tôi có thể khai báo 3 biến toàn cục global.jsvà truy cập chúng trong bất kỳ .jstệp nào trong 3 tệp khác khi tôi tải tất cả 4 tệp ở trên vào một tài liệu HTML không?

Ai đó có thể vui lòng cho tôi biết nếu điều này là có thể hoặc có một công việc xung quanh để đạt được điều này?

Câu trả lời:


96

Chỉ cần xác định các biến của bạn trong global.js bên ngoài phạm vi hàm:

// global.js
var global1 = "I'm a global!";
var global2 = "So am I!";

// other js-file
function testGlobal () {
    alert(global1);
}

Để đảm bảo rằng điều này hoạt động, bạn phải bao gồm / liên kết đến global.js trước khi cố gắng truy cập bất kỳ biến nào được xác định trong tệp đó:

<html>
    <head>
        <!-- Include global.js first -->
        <script src="/YOUR_PATH/global.js" type="text/javascript"></script>
        <!-- Now we can reference variables, objects, functions etc. 
             defined in global.js -->
        <script src="/YOUR_PATH/otherJsFile.js" type="text/javascript"></script>
    </head>
    [...]
</html>

Tất nhiên, bạn có thể liên kết trong các thẻ script ngay trước thẻ đóng <body> nếu bạn không muốn việc tải các tệp js làm gián đoạn quá trình tải trang đầu tiên.


4
Mặc dù câu trả lời này đúng, tôi khuyên bạn nên xác định phạm vi biến Javascript của Google để hiểu rõ hơn và có thể tránh làm những việc theo cách chính xác này.
aleemb

1
Đã đồng ý. Tôi luôn cố gắng xác định phạm vi tất cả các hàm và biến trong một "không gian tên" chung để tránh lộn xộn và xung đột. Thông thường tôi đặt tên nó là tên viết tắt của dự án hoặc công ty.
PatrikAkerstrand

Từ chối câu trả lời này và những người khác thích nó vì nó giả định rằng biến toàn cục sẽ được tạo trong phạm vi toàn cục và nó cũng yêu cầu lần đề cập đầu tiên của biến phải ở phạm vi toàn cục trước tất cả các đề cập khác.
Andrew

1
@Andrew Câu trả lời này đã được viết cách đây 8 năm. Đối với tất cả các ý định và mục đích, nó đã đúng vào thời điểm đó. Nếu bạn muốn thực sự đóng góp, bạn có thể muốn đề xuất một chỉnh sửa thay thế?
PatrikAkerstrand

@PatrikAkerstrand Việc hẹn hò thực sự không có gì khác biệt. Các câu trả lời khác sử dụng đối tượng toàn cục là đủ; Tôi đã giải thích tại sao điều này không.
Andrew

89

Cách tiếp cận được đề xuất là:

window.greeting = "Hello World!"

Sau đó, bạn có thể truy cập nó trong bất kỳ chức năng nào:

function foo() {

   alert(greeting); // Hello World!
   alert(window["greeting"]); // Hello World!
   alert(window.greeting); // Hello World! (recommended)

}

Cách tiếp cận này được ưa thích vì hai lý do.

  1. Ý định là rõ ràng. Việc sử dụng vartừ khóa có thể dễ dàng dẫn đến việc khai báo toàn cục varsđược dự định là cục bộ hoặc ngược lại. Loại phạm vi thay đổi này là một điểm gây nhầm lẫn cho nhiều nhà phát triển Javascript. Vì vậy, theo nguyên tắc chung, tôi đảm bảo rằng tất cả các khai báo biến đều được đặt trước từ khóa varhoặc tiền tố window.

  2. Bạn chuẩn hóa cú pháp này để đọc các biến theo cách này, điều đó có nghĩa là phạm vi cục bộ varkhông ảnh hưởng đến toàn cục varhoặc ngược lại. Ví dụ, những gì xảy ra ở đây là mơ hồ:

 

 greeting = "Aloha";

 function foo() {
     greeting = "Hello"; // overrides global!
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // does it alert "Hello" or "Howdy" ?

Tuy nhiên, điều này sạch hơn nhiều và ít bị lỗi hơn (bạn không thực sự cần phải nhớ tất cả các quy tắc xác định phạm vi biến):

 function foo() {
     window.greeting = "Hello";
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // alerts "Howdy"

Việc đính kèm các biến vào cửa sổ sẽ hoạt động trên tất cả các trình duyệt (và cũng là cách tôi áp dụng, +1!).
Dandy

1
@Dan, nếu bạn khai báo "var testvar = 'hello';" bên ngoài một hàm, nó sẽ tự động được thêm vào đối tượng window và bạn có thể truy cập nó bằng "window.testvar".
zkent

1
@zkent, đúng vậy, nhưng sử dụng đối tượng Window vẫn tốt hơn vì bạn có thể muốn biến mã của mình thành sth như cà phê sau này.
Nami WANG

Sử dụng tiền tố Window có tốt hơn không?
Andrew

7

Bạn đã thử chưa?

Nếu bạn làm:

var HI = 'Hello World';

Trong global.js. Và sau đó làm:

alert(HI);

Trong js1.jsđó sẽ cảnh báo nó tốt. Bạn chỉ cần đưa vào global.jstrước phần còn lại trong tài liệu HTML.

Điểm duy nhất là bạn phải khai báo nó trong phạm vi của cửa sổ (không phải bên trong bất kỳ hàm nào).

Bạn có thể chỉ cần loại bỏ varmột phần và tạo chúng theo cách đó, nhưng đó không phải là cách thực hành tốt.


7

Như đã đề cập ở trên, có vấn đề với việc sử dụng phạm vi cao nhất trong tệp tập lệnh của bạn. Đây là một vấn đề khác: Tệp tập lệnh có thể được chạy từ một ngữ cảnh không phải là ngữ cảnh chung trong một số môi trường thời gian chạy.

Nó đã được đề xuất để chỉ định toàn cầu windowtrực tiếp. Nhưng điều đó cũng phụ thuộc vào thời gian chạy và không hoạt động trong Node, v.v. Nó cho thấy rằng quản lý biến toàn cục di động cần một số cân nhắc cẩn thận và nỗ lực thêm. Có thể họ sẽ sửa nó trong các phiên bản ECMS trong tương lai!

Hiện tại, tôi muốn giới thiệu một cái gì đó như thế này để hỗ trợ quản lý toàn cầu thích hợp cho tất cả các môi trường thời gian chạy:

/**
 * Exports the given object into the global context.
 */
var exportGlobal = function(name, object) {
    if (typeof(global) !== "undefined")  {
        // Node.js
        global[name] = object;
    }
    else if (typeof(window) !== "undefined") {
        // JS with GUI (usually browser)
        window[name] = object;
    }
    else {
        throw new Error("Unkown run-time environment. Currently only browsers and Node.js are supported.");
    }
};


// export exportGlobal itself
exportGlobal("exportGlobal", exportGlobal);

// create a new global namespace
exportGlobal("someothernamespace", {});

Việc gõ nhiều hơn một chút, nhưng nó giúp cho việc quản lý biến toàn cầu của bạn trở nên bền vững trong tương lai.

Tuyên bố từ chối trách nhiệm: Một phần của ý tưởng này đến với tôi khi xem các phiên bản trước của stacktrace.js .

Tôi nghĩ, người ta cũng có thể sử dụng Webpack hoặc các công cụ khác để phát hiện môi trường thời gian chạy đáng tin cậy hơn và ít bị hack hơn.


2
GLOBALhiện không được dùng nữa và globalsẽ được sử dụng thay thế.
Thomas

2

Có, bạn có thể truy cập chúng. Bạn nên khai báo chúng trong 'không gian công cộng' (bên ngoài bất kỳ chức năng nào) như:

var globalvar1 = 'value';

Bạn có thể truy cập chúng sau này, cũng trong các tệp khác.

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.