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的解释执行,也称逐行执行,就得出了文章开头代码中的输出结果