You can define your variables in JavaScript using two keywords - the let keyword and the var keyword. The var keyword is the oldest way of defining and declaring variables in JavaScript whereas the let is fairly new and was introduced by ES15.
您可以使用兩個關鍵字( let關鍵字和var關鍵字) 在JavaScript中定義變量 。 var關鍵字是在JavaScript中定義和聲明變量的最古老的方法,而let是相當新的,是ES15引入的。
In this article, we'll look at the differences between the two so you know when to use which for your variables.
在本文中,我們將研究兩者之間的區別,以便您知道何時將哪個變量用于變量。
Open the chrome dev console to try out the examples by right-clicking on the browser → selecting inspect → selecting console or simply type f12.
通過右鍵單擊瀏覽器→選擇檢查→選擇控制臺,打開chrome dev控制臺以嘗試示例,或者直接鍵入f12。
Example 1:
范例1:
var size=32;
console.log(size);
Output
輸出量
32
Example 2:
范例2:
var size=63;
console.log(size);
Output
輸出量
63
We declared a variable size with a value 32. Then we redeclared it with another value, 63. Everything looks fine till now.
我們聲明了一個可變大小,值為32 。 然后,我們用另一個值63對其進行了重新聲明。 到目前為止一切都很好。
let length=14;
console.log(length);
Output
輸出量
14
let length=14;
let length=20; //will produce error
console.log(length);
Output
輸出量
Uncaught SyntaxError: Identifier 'length' has already been declared
at <anonymous>:1:1
let length=14;
length=20; //no produce error
console.log(length);
Output
輸出量
20
Now we create a length variable with a value 14 but this time using the let keyword. When we redeclare the same variable with another value we get a SyntaxError saying it has already been declared. The first point of difference between let and var is that using var we can redeclare those variables but with let, we can only redefine them, not redeclare them. When we reassign the value 20 to the variable length, we get no error on the console and our length variable happily takes a new value.
現在我們創建一個長度變量,值為14,但是這次使用let關鍵字 。 當我們用另一個值重新聲明相同的變量時,我們得到一個SyntaxError,它已經被聲明。 let和var之間的第一點區別是,使用var可以重新聲明這些變量,但是使用let ,我們只能重新定義它們,而不能重新聲明它們。 當我們將值20重新分配給變量length時 ,在控制臺上沒有錯誤,并且我們的length變量愉快地采用了一個新值。
var ironMan = 'red';
var captainAmerica = 'blue';
if (ironMan === 'red') {
var ironMan = 'silver';
let captainAmerica = 'golden';
console.log(ironMan);
console.log(captainAmerica);
}
Output
輸出量
silver
Golden
var ironMan = 'red';
var captainAmerica = 'blue';
if (ironMan === 'red') {
var ironMan = 'silver';
let captainAmerica = 'golden';
console.log(ironMan);
console.log(captainAmerica);
}
Output
輸出量
silver
Blue
The next difference between the two is the scope. You can observe from the above code that captainAmerica is declared again inside using the let keyword with a value 'golden' and inside that if block it persists that value, however, outside that if block when we log it's value to the console we get the older value 'blue' which was defined outside the if block. Thus variables declared using the let keyword have block scope. On the other hand, we changed the value of ironMan inside the if block and it continues to hold that value even after the if block is over. We can say that var takes the scope of it's enclosing execution context which can be a function or even the global scope as in this case.
兩者之間的下一個區別是范圍。 您可以從上面的代碼中觀察到,在captainAmerica內部再次使用let關鍵字聲明了“黃金”值,并且在if塊內部將其持久保留該值,但是在if塊之外,當我們將其值記錄到控制臺時,我們得到了在if塊外定義的舊值“ blue” 。 因此,使用let關鍵字聲明的變量具有塊范圍。 另一方面,我們更改了if塊內的ironMan的值, 即使 if塊結束,它仍繼續保持該值。 我們可以說var接受其封閉執行上下文的范圍,在這種情況下,它可以是函數甚至是全局范圍。
Heads up: The reason let was introduced was to avoid using global variables and namespaces everywhere. It's a bad, no wait, terrible programming habit. Avoid using global variables where their global scope renders absurd. Use let wherever possible.
注意:引入let的原因是為了避免在各處使用全局變量和名稱空間。 這是一種不好的,迫不及待的可怕的編程習慣。 避免在全局變量變得荒謬的地方使用全局變量。 盡可能使用let 。
Finally, the last difference I want to talk about is Hoisting. Consider the following piece of code,
最后,我要談的最后一個區別是吊裝 。 考慮下面的代碼,
x = 5;
console.log(x);
var x;
Output
輸出量
5
If you've worked with languages like C/C++ you might find it strange. In such languages, you can expect an error saying something like x is not defined because compiler reads from top to bottom. So is JS also executed from top to bottom? Well, if it were, you wouldn't be able to do this. Then how come we can use a variable and declare it later? The answer is hoisting. Hoisting means moving all declarations to the top. This means that while executing the code, all variable declarations are on the top so till the time you come to x=5 line you already know that x has been declared a variable somewhere in the program.
如果您使用過C / C ++之類的語言,則可能會覺得很奇怪。 在這樣的語言中,您可能會遇到一個錯誤,即未定義類似x的內容,因為編譯器從上到下讀取。 JS也是從頭到尾執行嗎? 好吧,如果是這樣,您將無法做到這一點。 那么我們如何使用變量并在以后聲明它呢? 答案正在提升。 吊裝意味著將所有聲明移到頂部。 這意味著在執行代碼時,所有變量聲明都位于頂部,因此直到您到達x = 5行時,您已經知道x已在程序中的某個位置聲明為變量。
y = 3;
function setRandom(y) {
console.log('Before declaring y: ', y);
}
setRandom();
var y;
console.log('After declaring y: ', y);
Output
輸出量
Before declaring y: undefined
After declaring y: 3
Let's try to hoist a variable using let,
讓我們嘗試使用let提升變量,
x = 5;
console.log(x);
let x;
Output
輸出量
VM2466:1 Uncaught ReferenceError: Cannot access 'x' before initialization
at <anonymous>:1:2
We get an error saying we can't access it before it is even initialized. So are variables declared with the let keyword not hoisted? They are, but they're hoisted in a temporal dead zone. A zone where you can use variables that have not been defined yet.
我們收到一條錯誤消息,說我們甚至無法在初始化之前訪問它。 那么,沒有懸掛用let關鍵字聲明的變量嗎? 它們是,但是它們被吊在一個臨時的死區中。 您可以在其中使用尚未定義的變量的區域。
Note: if you are using strict mode in your JavaScript then you're more likely to run into getting undefined values for such types of code because strict mode does not allow any hoisting to take place.
注意:如果您在JavaScript中使用嚴格模式,那么您很可能會遇到此類代碼的未定義值,因為嚴格模式不允許任何提升。
So is hoisting in TDZ useless? Well not really, consider the following example using an asynchronous function.
那么在TDZ中吊起是沒有用的嗎? 并非如此,請考慮以下使用異步函數的示例。
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000)
}
Output
輸出量
3
Out setTimeout is an asynchronous function and after 1 sec it prints the value of i which was incremented 4 times while that asynchronous function was running. However if we use let instead of var,
setTimeout輸出是一個異步函數,在1秒鐘后它將打印i的值,該值在該異步函數運行時增加了4倍。 但是,如果我們使用let而不是var ,
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000)
}
Output
輸出量
0
1
2
Now we get all the values that i took during that loop traversal. This is because of the TDZ or the temporal dead zone where let is hoisted. Thus using async can help you retain your values through TDZ hoisting if you use let instead of var. Remember to clean your code by replacing all var with let and make it a good practice to use block scopes instead of global scopes!
現在,我們所有的值, 我該循環遍歷期間舉行。 這是因為TDZ或懸掛了let 的時間盲區 。 因此,如果使用let而不是var,則使用async可以幫助您通過TDZ提升保留值。 請記住通過用let替換所有var來清理代碼,并使其成為使用塊范圍而不是全局范圍的好習慣!
翻譯自: https://www.includehelp.com/code-snippets/var-vs-let-in-javascript.aspx