摘要
函数是javascript中非常重要的一种编程思维,了解函数可以让我们更好地进行编程、解决问题,效率更高。
其中函数的预编译环节就会发生一些奇妙的过程
-
预编译发生在函数执行的前一刻
-
当函数被定义时 并没有发生预编译
-
当函数在执行的前一刻 预编译就已经完成了
预编译可以解决什么问题
有时候大家可能会解决这样的问题(比如面试的时候)
function a(a){
console.log(a);
function b(){};
console.log(b);
var b = 234;
console.log(b);
var a = 123;
console.log(a);
}
a(1);
预编译的过程
以下代码解决上面提出的问题
-
生成一个AO对象
AO : Activity Object 活跃对象 也叫执行期上下文
AO{}
- 找形参和变量声明 把形参和变量名作为属性名放到AO对象中并赋值为undefined
AO{
a : undefined, //形参和变量声明一致时写一个即可
b : undefined
}
- 把形参和实参相统一(把实参赋值到形参里)
AO{
a : 1,
b : undefined
}
- 函数声明提升 把函数名作为属性名放到AO对象中并赋值为函数体
AO{
a : 1,
b : function b(){} //函数声明和变量声明一致时 函数声明会覆盖变量声明
}
那么
function a(a){
console.log(a); //1
function b(){};
console.log(b); //function b(){}
var b = 234;
console.log(b); //234
var a = 123;
console.log(a); //123
}
a(1);
通过解决上面的问题我们可以发现,函数声明的优先级更高(由于函数提升发生在预编译过程的最后一步),所以函数声明会覆盖和它名字相同的变量声明。
function demo(){
console.log(a); //在a被赋值前打印的结果为 function a(){}
var a = 123;
console.log(a); // 在a被赋值后打印的结果为 123
function a(){}
}
demo();