ES6 塊級繫結
var 宣告與變數提升
使用 var 關鍵字宣告的變數,無論其實際宣告位置在何處,都會被視為宣告於所在函式的頂部,如果宣告不在任意函式內,則視為在全域性作用域的頂部。
function getValue(condition) {
if (condition) {
var value = "blue";
// 其他程式碼
return value;
} else {
// value 在此處可訪問,值為 undefined return null;
}
// value 在此處可訪問,值為 undefined
}
如果你不太熟悉 JS ,或許會認為僅當 condition 的值為 true 時,變數 value 才會被建立。但實際上,value 無論如何都會被建立。 JS 引擎在後臺對 getValue 函式進行了調整, 就像這樣:
function getValue(condition) {
var value;
if (condition) {
value = "blue";
// 其他程式碼
return value;
} else {
return null;
}
}
value 變數的宣告被提升到了頂部,而初始化工作則保留在原處。這意味著在 else 分支內 value 變數也是可訪問的,此處它的值會是 undefined ,因為它並沒有被初始化。
塊級宣告
塊級宣告也就是讓所宣告的變數在指定塊的作用域外無法被訪問(在一個函式內部 或 在一個程式碼塊內部)。
let 宣告
let 宣告的語法與 var 的語法一致。你基本上可以用 let 來代替 var 進行變數宣告,但會將變數的作用域限制在當前程式碼塊中(其他細微差別會在稍後討論)。由於 let 宣告並不會被提升到當前程式碼塊的頂部,因此你需要手動將 let 宣告放置到頂部,以便讓變數在整個程式碼塊內部可用。
function getValue(condition) {
if (condition) {
let value = "blue";
// 其他程式碼
return value;
} else {
// value 在此處不可用
return null;
}
// value 在此處不可用
}
禁止重複宣告
如果一個識別符號已經在程式碼塊內部被定義,那麼在此程式碼塊內使用同一個識別符號進行 let 宣告就會導致丟擲錯誤。
var count = 30;
// 語法錯誤
let count = 40;
在巢狀的作用域內使用 let 宣告一個同名的新變數,則不會丟擲錯誤。
var count = 30;
// 不會丟擲錯誤
if (condition) {
let count = 40;
// 其他程式碼
}
常量宣告
ES6 中裡也可以使用 const 語法進行宣告。使用 const 宣告的變數會被認為是常量( constant ),意味著它們的值在被設定完成後就不能再被改變。正因為如此,所有的 const 變數都需要在宣告時進行初始化。試圖對之前用 const 宣告的常量進行賦值會丟擲錯誤。
// 有效的常量
const maxItems = 30;
// 語法錯誤:未進行初始化
const name;
// 丟擲錯誤
const maxItem = 50;
常量宣告與 let 宣告一樣,都是塊級宣告。這意味著常量在宣告它們的語句塊外部是無法訪問的,宣告不會被提升,並且在同一個作用域內不能重複定義。
使用 const 宣告物件比較特殊,const 宣告會阻止對於變數繫結與變數自身值的修改,這意味著 const 宣告並不會阻止對變數成員的修改。
const person = {
name: "Nicholas"
};
// 工作正常
person.name = "Greg";
// 丟擲錯誤
person = {
name: "Greg"
}
暫時性死區
當 JS 引擎檢視接下來的程式碼塊並發現變數宣告時,它會在面對 var 的情況下將宣告提升到函式或全域性作用域的頂部,而面對 let 或 const 時會將宣告放在暫時性死區內。任何在暫時性死區內訪問變數的企圖都會導致“執行時”錯誤(runtime error)。只有執行到變數的宣告語句時,該變數才會從暫時性死區內被移除並可以安全使用。
迴圈中的塊級繫結
for (var i = 0; i < 10; i++) {
process(i);
}
// i 在此處仍然可被訪問
for (let i = 0; i < 10; i++) {
process(i);
}
// i 在此處不可訪問,丟擲錯誤
console.log(i);
因為 var 宣告導致了變數提升
迴圈內的常量宣告
在常規的 for 迴圈中,你可以在初始化時使用 const ,但迴圈會在你試圖改變該變數的值時丟擲錯誤。因為該語句試圖更改常量的值。因此,在迴圈中你只能使用 const 來宣告一個不會被更改的變數。
var funcs = [];
// 在一次迭代後丟擲錯誤
for (const i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
});
}
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"
});
全域性塊級繫結
- 當在全域性作用域上使用 var 時,它會建立一個新的全域性變數,併成為全域性物件(在瀏覽器中是 window )的一個屬性。這意味著使用 var 可能會無意覆蓋一個已有的全域性屬性。
- 若你在全域性作用域上使用 let 或 const ,雖然在全域性作用域上會建立新的繫結,但不會有任何屬性被新增到全域性物件上。這也就意味著你不能使用 let 或 const 來覆蓋一個全域性變數,你只能將其遮蔽。
- 當你不想在全域性物件上建立屬性時,這種特性會讓 let 與 const 在全域性作用域中更安全。
- 想讓程式碼能從全域性物件中被訪問,你仍然需要使用 var 。在瀏覽器中跨越幀或視窗去訪問程式碼時,這種做法非常普遍。
塊級繫結最佳實踐
在預設情況下使用 const ,而只在你知道變數值需要被更改的情況下才使用 let 。這在程式碼中能確保基本層次的不可變性,有助於防止某些型別的錯誤。
相關文章
- es6塊級繫結筆記筆記
- 深入理解ES6--1.塊級繫結
- ES6之塊級作用域
- 【深入淺出ES6】塊級變數變數
- ES6語法(一)塊級作用域、字串字串
- 草稿 核取方塊繫結資料 1204
- 重讀《深入理解ES6》 —— 塊級作用域
- ES6深入學習(一)塊級作用域詳解
- iis配置繫結二級域名的問題
- 怎麼透過.htaccess配置二級域名繫結
- 理解靜態繫結與動態繫結
- 事件繫結事件
- this 繫結解析
- SSL證書繫結域名還是繫結IP?
- vue 雙向繫結(v-model 雙向繫結、.sync 雙向繫結、.sync 傳物件)Vue物件
- 塊級、內聯、內聯塊級
- java中的靜態繫結與動態繫結Java
- IOC容器的繫結解析過程(繫結單例)單例
- C++的動態繫結和靜態繫結C++
- 使用ES6的新特性Proxy來實現一個資料繫結例項
- wpf RelativeSource繫結
- JavaScript 事件繫結JavaScript事件
- 資料繫結
- 延遲繫結
- JSX繫結事件JS事件
- js on繫結事件JS事件
- IIS中配置實現網站二級域名繫結方式整理網站
- Go Web輕量級框架Gin學習系列:資料繫結GoWeb框架
- 阿里雲如何繫結域名(阿里雲域名如何繫結ip)阿里
- python-物件導向(繫結方法與非繫結方法)Python物件
- 第二講、Vue3.x繫結資料、繫結html、繫結屬性、迴圈資料VueHTML
- SSL證書繫結了頂級域名後二級域名還需再申請嗎
- 深入解析 WezTerm 的自定義功能:鍵繫結和滑鼠繫結
- ROS指令碼ip-mac繫結 批次繫結ip和macROS指令碼Mac
- 【ES6總結】
- 如何編寫一個前端框架之五-基於 ES6 代理的資料繫結(譯)前端框架
- Hooks與事件繫結Hook事件
- 類,物件繫結方法物件