深入理解javascript變數宣告

NO IMAGE

相對於C/C 來說,ECMAScript裡的for迴圈並不能建立一個區域性的上下文。

複製程式碼 程式碼如下:
for (var k in {a: 1, b: 2}) {
  alert(k);
}

alert(k); // 儘管迴圈已經結束但變數k依然在當前作用域
任何時候,變數只能通過使用var關鍵字才能宣告。
 
上面的賦值語句:
 
a = 10;
這僅僅是給全域性物件建立了一個新屬性(但它不是變數)。“不是變數”並不是說它不能被改變,而是指它不符合ECMAScript規範中的變數概念,所以它“不是變數”(它之所以能成為全域性物件的屬性,完全是因為javascript中存在一個global物件,這樣的操作不是宣告一個變數而是給global物件增加一個a屬性。
 
下面看一個簡單的例題來說明問題

複製程式碼 程式碼如下:
if (!(“a” in window)) {
    var a = 1;
}
alert(a);

首先,所有的全域性變數都是window的屬性,語句 var a = 1;等價於window.a = 1;
 
你可以用如下方式來檢測全域性變數是否宣告
 
“變數名稱” in window

第二,所有的變數宣告都在範圍作用域的頂部,看一下相似的例子:
 
複製程式碼 程式碼如下:
alert(“a” in window);
var a;

此時,儘管宣告是在alert之後,alert彈出的依然是true,這是因為JavaScript引擎首先會掃墓所有的變數宣告,然後將這些變數宣告移動到頂部,最終的程式碼效果是這樣的:

複製程式碼 程式碼如下:
var a;
alert(“a” in window);

第三,你需要理解該題目的意思是,變數宣告被提前了,但變數賦值沒有,因為這行程式碼包括了變數宣告和變數賦值。

你可以將語句拆分為如下程式碼:

複製程式碼 程式碼如下:
var a;    //宣告
a = 1;    //初始化賦值

所以總結起來就是當變數宣告和賦值在一起用的時候,JavaScript引擎會自動將它分為兩部以便將變數宣告提前,不將賦值的步驟提前是因為他有可能影響程式碼執行出不可預期的結果。

題目中的程式碼相當於:

複製程式碼 程式碼如下:
var a;
if (!(“a” in window)) {
    a = 1;
}
alert(a);

根據上述例題的分析,宣告變數時如果是宣告的區域性變數前面一定要加var,如果宣告的是全域性變數可以不加var(最好限制全域性變數的個數,儘量使用區域性變數)

下面講述一個使用var的幾個特性

使用var語句多次宣告一個變數不僅是合法的,而且也不會造成任何錯誤。
如果重複使用的一個宣告有一個初始值,那麼它擔當的不過是一個賦值語句的角色。
如果重複使用的一個宣告沒有一個初始值,那麼它不會對原來存在的變數有任何的影響。
沒有var宣告的變數,是作為全域性變數存在的;有var宣告的變數,屬於區域性變數,尤其是在函式內部。並且,經過測試,帶var宣告比不帶var速度要快。函式內儘量多設區域性變數,這樣即安全又快速,變數操作也更加合理,不會因為函式內胡亂操作全域性變數而導致邏輯錯誤。

宣告物件時最好使用物件自面量的方式,這樣的速度相對new的方式要快很多。

變數名是自己取的,為了照顧語義和規範,變數名可能稍長,但是注意了,變數名的長度也會影響程式碼的執行速度。長的變數名宣告的執行速度沒有短的快。

您可能感興趣的文章:

var與Javascript變數隱式宣告Javascript var變數隱式宣告方法javascript迴圈變數註冊dom事件 之強大的閉包關於JavaScript中var宣告變數作用域的推斷基於JavaScript 宣告全域性變數的三種方式詳解一個JavaScript變數宣告的知識點JavaScript宣告變數時為什麼要加var關鍵字JavaScript變數宣告詳解javascript定義變數時加var與不加var的區別javascript定義變數時帶var與不帶var的區別分析JavaScript判斷變數是否為空的自定義函式分享javascript中區域性變數和全域性變數的區別詳解JavaScript 變數、作用域及記憶體javascript判斷變數是否有值的方法JavaScript宣告變數名的語法規則淺析四種常見的Javascript宣告迴圈變數的書寫方式