js预编译阶段干了什么事

278 阅读1分钟
function fn(a,c){
    console.log(a)  //function a 被同名函数覆盖了
    var a = 123
    console.log(a) // 123
    console.log(c) // function c 被同名函数覆盖了
    function a(){}
    if(false){
        var d = 678
    }
    console.log(d)  //undefined  变量在预编译阶段已声明,也就是平常说的变量声明提升,上面条件语句没有成立,所以没有被赋值
    console.log(b)  //undefined   b是变量,不是函数
    var b = function(){}   //赋值给变量的函数称之为函数表达式
    console.log(b)  //function()  经上面表达式赋值操作
    function c(){}
    console.log(c). //function c  c还是函数没有变化

}
fn(1,2)

预编译: 预编译阶段也就是作用域的创建阶段。
在函数的作用域创建阶段,有一个与之对应的js变量对象,也称为AO对象。他是开发者访问不到的,是供JS引擎自己去访问的。

这时候要做几件事:
1.创建AO对象
2.找形参和变量的声明 作为AO对象的属性名 值是undefined
3.实参和形参相统一
4.找函数的声明 会覆盖变量的声明

上面代码的预编译阶段开始:
1.创建AO对象 2.找形参和变量的声明 作为AO对象的属性名 值是undefined

AO:{
a:undefined,
c:undefined,
d:undefined,
b:undefined,
}

3.实参和形参相统一 函数调用语句的实参赋值给形参

AO:{
a:1,  
c:2,  
d:undefined,
b:undefined,
}

4.找函数的声明 会覆盖同名变量的声明

AO:{
a:function a(){},
c:function c(){},
d:undefined,
b:undefined,
}

上面代码的预编译阶段结束
接下来进行JS的解释执行,也称逐行执行,就得出了文章开头代码中的输出结果