總結自:https://blog.csdn.net/DurianPudding/article/details/87953939
一言以蔽之:編輯器會在作用域判斷這是重名聲明時,忽略var直接賦值
首先說明JS代碼運行時三者的作用:
引擎負責整個代碼的編譯以及運行
編譯器則負責詞法分析、語法分析、代碼生成等工作
作用域負責維護所有的標識符(變量)。
例:
var a = 2; var a = 3; a = 4; alert(a); // 4
重復聲明時:首先,編譯器對代碼進行分析拆解,當遇見var a,則詢問作用域是否已存在叫a的變量,若不存在,則要求作用域聲明一個新的變量a,若已存在,則忽略var繼續向下編譯。
賦值時:引擎遇見a=2時同樣會詢問在當前的作用域下是否有變量a。若存在,則將a賦值為2;若不存在,則順着作用域鏈向上查找,若最終找到了變量a則將其賦值2,若沒有找到,則招呼作用域聲明一個變量a並賦值為2(這就是為什么第二段代碼可以正確執行且a變量為全局變量的原因,當然,在嚴格模式下JS會直接拋出異常:a is not defined)。