您好,登錄后才能下訂單哦!
小編給大家分享一下es6塊級綁定中let and const的案例,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
變量聲明一直是js工作中最微妙的一部分,它不像C語言一樣,變量總是在被它創建的時候聲明,js語言可以允許你在你需要聲明變量的時候進行聲明。
var let const 之變量聲明
var 聲明與變量提升。
當我們使用var關鍵字進行變量聲明的時候,無論變量聲明的位置在哪里,都會被是為聲明于所在的函數的頂部(如果不在函數內的話,則視為在全局作用域的頂部)這就是所謂的變量提升(hoisting)
var提升如下:
function getValue(condition) { if (condition) { var value = "blue"; // 其他代碼 return value; } else { // value 在此處可訪問,值為 undefined return null; } // value 在此處可訪問,值為 undefined }
如下所示:
function getValue(condition) { if (condition) { let value = "blue"; // 其他代碼 return value; } else { // value 在此處不可用 return null; } // value 在此處不可用 }
如果一個標識符已經在代碼內部被定義,重復進行let聲明會報錯
var a = 30; //報錯 let a = 30;
var count = 30; // 不會拋出錯誤 if (condition) { let count = 40; // 其他代碼 }
// 有效的常量 const maxItems = 30; // 語法錯誤:未進行初始化 const name;
const person = { name: "Nicholas" }; // 工作正常 person.name = "Greg"; // 拋出錯誤 person = { name: "Greg" };
if (condition) { const maxItems = 5; // 其他代碼 } // maxItems 在此處無法訪問
for (var i = 0; i < 10; i++) { process(items[i]); } // i 在此處仍然可被訪問 console.log(i); // 10
輸出的結果并不是預期的值而是10;是因為var聲明導致的變量的提升。聰明的你肯定會想到使用塊級綁定來進行變量聲明
for (let i = 0; i < 10; i++) { process(items[i]); } console.log(i);
i在此處是不是會正常輸出呢,其實不會,在這個例子中會導致報錯,為什么呢?因為i在此處不可訪問。本例中的變量 i 僅在 for 循環內部可用,一旦循環結束,該變量在任意位置都不可訪問。
我們在來看看一下代碼
var funcs = []; for (var i = 0; i < 10; i++) { funcs.push(function() { console.log(i); }); } funcs.forEach(function(func) { func(); // 輸出數值 "10" 十次 });
你原本可能預期這段代碼會輸出 0 到 9 的數值,但它卻在同一行將數值 10 輸出了十次。這是因為變量 i 在循環的每次迭代中都被共享了,意味著循環內創建的那些函數都擁有對于同一變量的引用。在循環結束后,變量 i 的值會是 10 ,因此當 console.log(i) 被調用時,
每次都打印出 10 。
為了修正這個問題,開發者在循環內使用立即調用函數表達式(IIFEs),以便在每次迭代中強制創建變量的一個新副本,示例如下:
var funcs = []; for (var i = 0; i < 10; i++) { funcs.push((function(value) { return function() { console.log(value); } }(i))); } funcs.forEach(function(func) { func(); // 從 0 到 9 依次輸出 });
let 聲明通過有效模仿上例中 IIFE 的作用而簡化了循環。在每次迭代中,都會創建一個新的
同名變量并對其進行初始化。這意味著你可以完全省略 IIFE 而獲得預期的結果,就像這樣
var funcs = []; for (let i = 0; i < 10; i++) { funcs.push(function() { console.log(i); }); } funcs.forEach(function(func) { func(); // 從 0 到 9 依次輸出 })
我們是否會想到這個問題:為什么同樣的代碼使用let聲明會導致不一樣的結果呢?
在循環中let聲明每次都創建了一個新的i變量,因此在循環內部創建的函數獲得了各自的i副本,而每個i副本的值都會在每次的循環迭代聲明變量的時候確定了
var funcs = [], object = { a: true, b: true, c: true }; for (let key in object) { funcs.push(function() { console.log(key); }); } funcs.forEach(function(func) { func(); // 依次輸出 "a"、 "b"、 "c" });
本例中的 for-in 循環體現出了與 for 循環相同的行為。每次循環,一個新的 key 變量綁定就被創建,因此每個函數都能夠擁有它自身的 key 變量副本,結果每個函數都輸出了一個不同的值。而如果使用 var 來聲明 key ,則所有函數都只會輸出 "c" 。
let 聲明在循環內部的行為是在規范中特別定義的,而與不提升變量聲明的特征沒有必然聯系。事實上,在早期 let 的實現中并沒有這種行為,它是后來才添加的。
循環內的常量聲明
雖然es6沒有明確的規范我們不能在for循環中使用const聲明,然而它會根據循環方式的不同而有不同的行為,我們可以在初始化時使用const,但是當循環試圖改變變量的值的時候會拋出錯誤,例如:
var funcs = []; // 在一次迭代后拋出錯誤 for (const i = 0; i < 10; i++) { funcs.push(function() { console.log(i); }); }
在此代碼中, i 被聲明為一個常量。循環的第一次迭代成功執行,此時 i 的值為 0 。在
i++ 執行時,一個錯誤會被拋出,因為該語句試圖更改常量的值。因此,在循環中你只能使
用 const 來聲明一個不會被更改的變量
而另一方面, const 變量在 for-in 或 for-of 循環中使用時,與 let 變量效果相同。因
此下面代碼不會導致出錯:
var funcs = [], object = { a: true, b: true, c: true }; // 不會導致錯誤 for (const key in object) { funcs.push(function() { console.log(key); }); } funcs.forEach(function(func) { func(); // 依次輸出 "a"、 "b"、 "c" });
這段代碼與“循環內的 let 聲明”小節的第二個例子幾乎完全一樣,唯一的區別是 key 的值在
循環內不能被更改。 const 能夠在 for-in 與 for-of 循環內工作,是因為循環為每次迭
代創建了一個新的變量綁定,而不是試圖去修改已綁定的變量的值(就像使用了 for 而不是
for-in 的上個例子那樣)。
全局塊級綁定
let 與 const 不同于 var 的另一個方面是在全局作用域上的表現。當在全局作用域上使用 var 時,它會創建一個新的全局變量,并成為全局對象(在瀏覽器中是 window )的一
個屬性。
總結
let和const塊級作用域的引入,能夠使我們減少很多無心的錯誤,它們的一個副作用,是不能在變量聲明位置之前訪問它們
塊級綁定當前的最佳實踐就是:在默認情況下使用 const ,而只在你知道變量值需要被更改的情況下才使用 let 。這在代碼中能確保基本層次的不可變性,有助于防止某些類型的錯誤。
以上是“es6塊級綁定中let and const的案例”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。