文章參考:
https://time.geekbang.org/column/article/126339
https://github.com/mqyqingfeng/Blog/issues/4
執(zhí)行上下文
定義:當 JavaScript 代碼執(zhí)行一段可執(zhí)行代碼(executable code)時,會創(chuàng)建對應的執(zhí)行上下文(execution context)。
調用棧
調用棧是javascript引擎追蹤函數執(zhí)行的一個機制,通過調用棧就能夠了解函數之間的調用關系。javascript利用棧這種數據結構管理執(zhí)行上下文。
var a = 0;
function add(a + b) {
returan a + b;
}
function sum(c) {
return c + add(2, 3);
}
sum(a);
以上代碼執(zhí)行調用棧如下:

可以看到調用棧如果不能有序退出那么就會造成棧溢出,這種情況一般會發(fā)生在遞歸調用結束條件有問題情況等等。
塊級作用域
作用域決定了代碼區(qū)塊中變量和其他資源的可訪問性。
ES6 之前javascript沒有塊級作用域,只有全局作用域和函數作用域。var、let、const是js定義變量的三個關鍵詞,其中var和let、const有本質不同。let 和 const 都是es6語法。兩者都支持塊級作用域,并沒有變量提升現象,即:不會再編譯階段將聲明放置到代碼頂部。而在javascript為了加入塊級作用域,引入了詞法環(huán)境這一概念。我們可以簡單地認為,var以及function聲明的變量加入到環(huán)境變量,而let以及const聲明的變量加入到詞法環(huán)境當中。
我們可以通過一個函數的創(chuàng)建執(zhí)行來分析這兩種變量的不同。
function strong(){
var a = 1;
let b = 2;
{
var c = 3;
let d = 4;
console.log(c)
console.log(d)
}
console.log(a)
console.log(b)
console.log(c)
}
foo()
當函數創(chuàng)建并執(zhí)行的時候,會產生如下的調用棧:

當執(zhí)行到console.log(c) 的時候,調用棧如下:

可以看到 let , const 等塊級作用域變量會直接放到詞法環(huán)境中,首先在這里尋找變量,如果沒有再去變量環(huán)境中尋找。塊級代碼執(zhí)行完后,這些變量會被詞法環(huán)境棧直接彈出。