JavaScript預(yù)編譯四部曲:
- 創(chuàng)建AO(Activation Object)對象;
- 找形參和變量申明,將變量和形參名作為AO對象的屬性名,值為
undefined; - 將實(shí)參值和形參值相統(tǒng)一;
- 在函數(shù)體里面找函數(shù)申明,值賦予函數(shù)體。
這樣說比較難理解,我們來看個(gè)例子:
function fn (a) {
console.log(a)
var a = 123
console.log(a)
function a () {}
console.log(a)
var b = function () {}
console.log(b)
function d () {}
}
fn(1)
第一步,創(chuàng)建AO對象:
AO: {}
第二步,找形參和變量申明,將變量和形參名作為AO對象的屬性名,值為undefined:

image.png
根據(jù)上圖可得AO對象為:
AO: {
a: undefined,
b: undefined
}
第三部,將實(shí)參值和形參值相統(tǒng)一
例子中函數(shù)只有a一個(gè)形參,AO對象為
AO: {
a: 1,
b: undefined
}
第四部,在函數(shù)體里面找函數(shù)申明,值賦予函數(shù)體。
例子中函數(shù)申明如下圖:

image.png
如果函數(shù)申明的函數(shù)名和AO對象的屬性名相同,那么會覆蓋掉的AO原來的屬性值
AO對象的a屬性重復(fù)了,從而被覆蓋。故生成的AO對象為:
AO: {
a: function a () {}, //這里a被覆蓋了
b: undefined,
d: function d () {}
}
最后來看運(yùn)行結(jié)果:
function fn (a) {
// AO: { a: function a () {} }
console.log(a) // function a () {}
var a = 123 // 這里將AO的值改變成123 AO: {a: 123}
console.log(a) // 123
function a () {}
console.log(a) // 123
var b = function () {}
console.log(b) // function () {}
function d () {}
}
fn(1)