JS三種變量定義方式——全乾貨,拿走不謝!

js中三種定義變量的方式:const,var和let。 const——聲明一個只讀的命名常量。 var——聲明一個變量,可同時初始化。 let——聲明一個塊級本地變量,可以同時初始化。

JS三種變量定義方式——全乾貨,拿走不謝!

const常量

常量是塊級作用域,常量的值不能通過重新賦值來改變,並且不能重新聲明。

語法: const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]];

1.const聲明創建一個常量,其作用域可以是全局或本地聲明的塊。與var變量不同,全局常量不會變為窗口對象的屬性。需要一個常數的初始化器;也就是說,您必須在聲明的同一語句中指定它的值(這是有道理的,因為以後不能更改)。

JS三種變量定義方式——全乾貨,拿走不謝!

2.一個常量不能和它所在作用域內的其他變量或函數擁有相同的名稱。

JS三種變量定義方式——全乾貨,拿走不謝!

var變量

語法:var varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]];

var變量聲明,無論發生在何處,都在執行任何代碼之前進行處理。用var聲明的變量的作用域是它當前的執行上下文,它可以是嵌套的函數,也可以是聲明在任何函數外的變量。如果你重新聲明一個 JavaScript 變量,它將不會丟失其值。

將賦值給未聲明變量的值在執行賦值時將其隱式地創建為全局變量(它將成為全局對象的屬性)。聲明和未聲明變量之間的差異是:

1. 聲明變量的作用域限制在其聲明位置的上下文中,而非聲明變量總是全局的。

JS三種變量定義方式——全乾貨,拿走不謝!

2. 聲明變量在任何代碼執行前創建,而非聲明變量只有在執行賦值操作的時候才會被創建。

JS三種變量定義方式——全乾貨,拿走不謝!

3. 聲明變量是它所在上下文環境的不可配置屬性,非聲明變量是可配置的(如非聲明變量可以被刪除)。

JS三種變量定義方式——全乾貨,拿走不謝!

由於這三個差異,未能聲明變量將很可能導致意想不到的結果。因此,建議始終聲明變量,無論它們是在函數還是全局作用域內。 而在 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'才出現了這樣的結果。

多個變量的初始化

JS三種變量定義方式——全乾貨,拿走不謝!

隱式全局變量和外部函數作用域

看起來像是隱式全局作用域的變量也有可能是其外部函數變量的引用。

JS三種變量定義方式——全乾貨,拿走不謝!

let變量

let 語句聲明一個塊級作用域的本地變量,並且可選的將其初始化為一個值。

語法:let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];

1.作用域規則

let聲明的變量只在其聲明的塊或子塊中可用,這一點,與var相似。二者之間最主要的區別在於var聲明的變量的作用域是整個封閉函數。

JS三種變量定義方式——全乾貨,拿走不謝!

2.簡化內部函數代碼

當用到內部函數的時候,let會讓你的代碼更加簡單。

JS三種變量定義方式——全乾貨,拿走不謝!

上面這段代碼的意圖是創建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 初始化處理的”暫存死區“之中。

JS三種變量定義方式——全乾貨,拿走不謝!

在 switch 聲明中你可能會遇到這樣的錯誤,因為一個switch只有一個作用塊.

JS三種變量定義方式——全乾貨,拿走不謝!

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三種變量定義方式——全乾貨,拿走不謝!

let 對比 var

編程是一種修行,我願與志同道合的朋友攜手前行,一起探索有關編程的奧妙!

如果您在前端學習的過程中遇到難題,歡迎【關注】並【私信】我,大家一起交流解決!


分享到:


相關文章: