- JavaScript 是以 function 來建立新的變數 scope, 只要是在 function 之外宣告的變數都是全域變數, 也就是全域物件的屬性, 而只有全域變數可以不用加 var 宣告, 就可以直接使用。
- 有加 var 宣告的全域變數是全域物件 (在瀏覽器中就是 window) 的 non-configurable 屬性, 比如說你就無法使用 delete 刪除以 var 宣告的全域變數。
<!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-1.9.1.js"></script> </head> <body> <div id="da"></div> <div id="db"></div> <div id="dc"></div> <div id="dd"></div> <script> i = 10; var j = 20; this.i = 100; this.j = 200; $("#da").text(i); $("#db").text(j); $("#dc").text(this.i); $("#dd").text(window.j); </script> </body> </html>實際輸出的結果就是:
100你可以看到不論是用 i 或是 this.i 都是同一份資料, 這是因為 this 指向全域物件, 所以也可以用 window.j 以存取 j, 因為在瀏覽器中, window 就是全域物件。
200
100
200
如果你在剛剛的 JavaScript 程式中插入兩航程式, 嘗試用 delete 刪除 i 與 j:
i = 10; var j = 20; this.i = 100; this.j = 200; delete this.i; delete this.j; $("#da").text(i); $("#db").text(j); $("#dc").text(this.i); $("#dd").text(window.j);在瀏覽器的 JavaScript console 中就會看到以下的錯誤訊息:
Uncaught ReferenceError: i is not defined這是因為 i 並沒有使用 var 宣告, 是全域物件的 configurable 屬性, 因此可以用 delete 刪除, 所以當執行到底下存取變數 i 的值時, i 變數就已經不存在了。
事情還沒完, 如果你是使用 node.js, 那麼又複雜了一點, 使用 var 宣告的全域變數實際上不是真的全域, 而只能在模組 (可簡單看成是檔案) 內存取, 出了模組, 就無法存取了。以底下的程式為例:
i = 10; var j =20; console.log(global.i); console.log(global.j); console.log(i); console.log(j);執行結果如下:
10透過 node.js 的全域物件 global 可存取到沒有使用 var 宣告的 i 變數, 這是真正全域的變數。可是透過 global 物件嘗試存取 j 變數時, 就會看到 global.j 是未定義的屬性, 這表示 j 並不是真正全域的變數。
undefined
10
20
如果另外寫個程式把剛剛的測試程式當成模組載入:
var tv = require("./testvar.js"); console.log("global=============="); console.log(i); //console.log(j);輸出結果如下:
10可以看到在程式中可存取到在另一個檔案中宣告的變數 i, 的確是全域變數無誤。若是把程式中最後一行的註解拿掉, 嘗試存取 j, 就會看到:
undefined
10
20
global==============
10
10可以看到 j 並未定義, 這是因為 j 是用 var 在其他檔案中宣告的變數, 不是全域變數, 所以無法存取。
D:\mee\My Box Files\practice\jswebapp\testvar2.js:5
console.log(j);
^
ReferenceError: j is not defined
at Object.(D:\mee\My Box Files\practice\jswebapp\testvar2.js:5:13)