先記住口訣:
(1)作用域鏈實際上是對象列表,其中每個對象表示一個作用域,其中的屬性即爲變量名
(2)當函數作爲對象的方法調用時,其內的 this 指向該對象;當函數只作爲函數調用時,
其內的 this 爲 window (非嚴格模式) 或 undefined(嚴格模式)。[參考:《JavaScript權威指南》]
下面通過具體的案例來理解上面兩句話的含義:
代碼1:
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(new Date, i);
}, 1000);
}
console.log(new Date, i);
上述代碼的 for 循環沒執行一次,其 setTimeout() 中的函數都會放到回調隊列中,當其他代碼都執行完成(即此時 i = 5),纔會從回調隊列中調出存入的函數並依次執行。根據口訣 1 ,因爲最後 i = 5,所以上述程序的最終輸出結果爲:
5 => 這是 for 循環外 console.log() 執行的結果
5 5 5 5 5 => 這是 setTimeout() 中函數執行的結果
參考文獻
[1] 關於JavaScript 事件循環:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop
[2] 事件循環的視頻教程:https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=42s