先看個小例子
function fn(){ console.log(a);//undefined; var a = 1; } fn();
為什么打印出來的是 undefined 呢?
執行上下文概念
當代碼運行時,會產生一個對應的執行環境,在這個環境中,所有變量會被事先提出來(變量提升),有的直接賦值,有的為默認值 undefined,代碼從上往下開始執行,就叫做執行上下文。
在 JavaScript 的世界里,運行環境有三種,分別是:
1.全局環境:代碼首先進入的環境
2.函數環境:函數被調用時執行的環境
3.eval函數:https://www.cnblogs.com/chaoguo1234/p/5384745.html(不常用)
執行上下文特點
1.單線程,在主進程上運行
2.同步執行,從上往下按順序執行
3.全局上下文只有一個,瀏覽器關閉時會被彈出棧
4.函數的執行上下文沒有數目限制
5.函數每被調用一次,都會產生一個新的執行上下文環境
執行上下文棧
執行全局代碼時,會產生一個執行上下文環境,每次調用函數都又會產生執行上下文環境。當函數調用完成時,這個上下文環境以及其中的數據都會被消除,再重新回到全局上下文環境。處於活動狀態的執行上下文環境只有一個。
其實這是一個壓棧出棧的過程——執行上下文棧。
var // 1.進入全局上下文環境 a = 10, fn, bar = function(x){ var b = 20; fn(x + b); // 3.進入fn上下文環境 } fn = function(y){ var c = 20; console.log(y + c); } bar(5); // 2.進入bar上下文環境
執行上下文生命周期
如圖所示,執行上下文共分3個階段,分別是:
1.創建階段
(1).生成變量對象
(2).建立作用域鏈
(3).確定 this 指向
2.執行階段
(1).變量賦值
(2).函數引用
(3).執行其他代碼
3.銷毀階段
執行完畢出棧,等待回收被銷毀
所以上面小例子等同於:
function fn(){ var a; console.log(a); a = 1; } fn();