js是一门解释性语言,执行分三步:语法解析、预编译、解释执行。下面分析一下函数预编译过程(预编译发生在函数执行前的一刻)预编译分为四步:
1 创建AO对象(执行期上下文)
2 找到形参和变量声明,将变量和形参数名作为AO属性并且赋值为undefined
3 将实参和形参对号赋值
4 在函数体里面找到函数声明(如果有),值就是函数体
看下面代码代码:
function a(a){
console.log(a) //ƒ a(){}
var a = 123;
console.log(a) //123
function a(){}
var b = function(){}
console.log(b) //ƒ (){}
}
a(1)
函数执行前预编译四个步骤分析如下
// 1 创建AO对象
// AO = {
//
// }
// 2 形参和变量声明赋值为undefined
// AO={
// a:undefined,
// b:undefined,
// }
// 3 形参合实参统一
// AO={
// a:1,
// b:undefined,
// }
// AO 如果体内有函数声明 值为函数体{
// ao={
// a:function a(){},
// b:undefined,
// }
// }
再看另外一个例子
function test(a,b){
console.log(a) //1
c = 0;
var c;
console.log(c) // 0
a = 3;
b = 2;
console.log(b) //2
function b(){}
function d(){}
console.log(b) //2
}
test(1)
// 1 创建AO对象
// AO = {
//
// }
// 2 形参和变量声明赋值为undefined
// AO={
// a:undefined,
// b:undefined,
// c:undefined,
// }
// 3 形参合实参统一
// AO={
// a:1,
// b:undefined,
// c:undefined,
// }
// AO 如果体内有函数声明 值为函数体{
// ao={
// a:1,
// b:function b(){},
// c:undefined,
// }
// }
附:全局的预编译跟函数预编译原理一样(GO是执行期上下文)
function test(){
console.log(b) //undefined
if(a){
var b = 200
}
console.log(b) //undefined
c= 234
console.log(c) //234
}
var a;
test()
a = 200
console.log(c) //234
下面看另外一道题
function test(){
return foo;
foo = 10;
function foo(){}
var foo = 124
}
console.log(test()) //function foo(){}