js中三種定義變數的方式:const,var和let。 const——聲明一個只讀的命名常量。 var——聲明一個變數,可同時初始化。 let——聲明一個塊級本地變數,可以同時初始化。
常量是塊級作用域,常量的值不能通過重新賦值來改變,並且不能重新聲明。
語法: const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]];
1.const聲明創建一個常量,其作用域可以是全局或本地聲明的塊。與var變數不同,全局常量不會變為窗口對象的屬性。需要一個常數的初始化器;也就是說,您必須在聲明的同一語句中指定它的值(這是有道理的,因為以後不能更改)。
2.一個常量不能和它所在作用域內的其他變數或函數擁有相同的名稱。
語法:var varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]];
var變數聲明,無論發生在何處,都在執行任何代碼之前進行處理。用var聲明的變數的作用域是它當前的執行上下文,它可以是嵌套的函數,也可以是聲明在任何函數外的變數。如果你重新聲明一個 JavaScript 變數,它將不會丟失其值。
將賦值給未聲明變數的值在執行賦值時將其隱式地創建為全局變數(它將成為全局對象的屬性)。聲明和未聲明變數之間的差異是:
1. 聲明變數的作用域限制在其聲明位置的上下文中,而非聲明變數總是全局的。
2. 聲明變數在任何代碼執行前創建,而非聲明變數只有在執行賦值操作的時候才會被創建。
3. 聲明變數是它所在上下文環境的不可配置屬性,非聲明變數是可配置的(如非聲明變數可以被刪除)。
由於這三個差異,未能聲明變數將很可能導致意想不到的結果。因此,建議始終聲明變數,無論它們是在函數還是全局作用域內。 而在 ECMAScript 5 嚴格模式下,分配給未聲明的變數會引發錯誤。
聲明並初始化兩個變數
var a = 0, b = 0;
1.給兩個變數賦值成字元串值:
var a = "A"; var b = a; // 等效於: var a, b = a = "A";
2.留意其中的順序:
var x = y, y = A; console.log(x + y); // undefinedA
在這裡,x和y在代碼執行前就已經創建了,而賦值操作發生在創建之後。當"x = y"執行時,y已經存在,所以不拋出ReferenceError,並且它的值是undefined。所以x被賦予 undefined 值。然後,y被賦予A。於是在執行完第一行之後,x === undefined && y === A纔出現了這樣的結果。
多個變數的初始化
隱式全局變數和外部函數作用域
看起來像是隱式全局作用域的變數也有可能是其外部函數變數的引用。
let 語句聲明一個塊級作用域的本地變數,並且可選的將其初始化為一個值。
語法:let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
1.作用域規則
let聲明的變數只在其聲明的塊或子塊中可用,這一點,與var相似。二者之間最主要的區別在於var聲明的變數的作用域是整個封閉函數。
2.簡化內部函數代碼
當用到內部函數的時候,let會讓你的代碼更加簡單。
上面這段代碼的意圖是創建5個li,點擊不同的li能夠列印出當前li的序號。如果不用let,而改用var的話,將總是列印出 Item 5 is Clicked,因為 j 是函數級變數,5個內部函數都指向了同一個 j ,而 j 最後一次賦值是5。用了let後,j 變成塊級域(也就是花括弧中的塊,每進入一次花括弧就生成了一個塊級域),所以 5 個內部函數指向了不同的 j 。
在程序或者函數的頂層,let並不會像var一樣在全局對象上創造一個屬性,比如
var x = global; let y = global; console.log(this.x); // "global" console.log(this.y); // undefined
3.let 的暫存死區與錯誤
在同一個函數或同一個作用域中用let重複定義一個變數將引起 TypeError.
if (x) { let foo; let foo; // TypeError thrown. }
在 ECMAScript 2015 中,let 綁定不受變數提升的約束,這意味著 let 聲明不會被提升到當前執行上下文的頂部。在塊中的變數初始化之前,引用它將會導致 ReferenceError(而使用 var 聲明變數則恰恰相反,該變數的值是 undefined )。這個變數處於從塊開始到 let 初始化處理的」暫存死區「之中。
在 switch 聲明中你可能會遇到這樣的錯誤,因為一個switch只有一個作用塊.
3.循環定義中的let作用域
循環體中是可以引用在for聲明時用let定義的變數,儘管let不是出現在大括弧之間。
var i = 0; for (let i = i; i < 10; i++) { console.log(i); }
註:以上 let 聲明的 i 將會變成 undefined;chrome 版本50.0.2661.102 (64-bit);推薦以下寫法:
var i = 0; for (let l = i; l < 10; l++) { console.log(l); }
let的作用域是塊,而var的作用域是函數
let 對比 var
編程是一種修行,我願與志同道合的朋友攜手前行,一起探索有關編程的奧妙!如果您在前端學習的過程中遇到難題,歡迎【關注】並【私信】我,大家一起交流解決!
編程是一種修行,我願與志同道合的朋友攜手前行,一起探索有關編程的奧妙!
推薦閱讀:
帶你一分鐘理解JS閉包——通俗易懂
助你深入理解JS變數提升+為何let變數無法提升
淺談JS中變數提升——三分鐘讓你真正明白變數提升的含義
原文 山大王做前端的頭條主頁 - 今日頭條(www.toutiao.com)