JavaScript函数的预编译过程
前言
最近刚面了一家公司的前端,本来觉得自己技术还不错,结果面完才发现,以前学过的基础知识都忘了差不多了。真是大写的尴尬!!!以前学习的时候,总觉得能记住,现在才发现写博客的重要性。本着不服输的态度,从哪里跌倒就从哪里站起来,那么从原声js开始吧!
什么是函数的预编译?为什么要学习函数的预编译?
咱们思考一下这个函数的执行结果
// 这个函数的执行结果是什么??
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);
是不是看(((φ(◎ロ◎;)φ)))了。。。
如果想要弄明白函数 fn(1)的执行过程,那么就要仔细研究一下函数预编译的过程
那么,开始正文!!!
函数预编译发生的时间
在函数执行的前一刻,JavaScript就完成了预编译的整个过程。
函数预编译发生的过程
- 创建AO (Activation Object)对象 ,也就是执行期上下文;
- 找形参和变量声明,将形参和变量声明作为AO的属性 ;
- 将实参与形参相统一,就是将实参赋值给形参 ;
- 在函数体中找到函数声明,并将其作为AO的属性 ;
- 执行函数 ;
是不是有点绕,有点晕?。?
那么,咱们对照着上面的函数仔细分析一下啊
函数fn(1)的预编译过程
// 这个函数的执行结果是什么??
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);
- 创建AO (Activation Object)对象 ,也就是执行期上下文;
// 这个函数的执行结果是什么??
AO{
//这是一个AO对象;
}
- 找形参和变量声明,将形参和变量声明(只是变量声明,不包括变量赋值,变量赋值在函数执行时执行)作为AO的属性 ;
// 这个函数的执行结果是什么??
AO{
a:undefined //这是形参,也是变量声明
b:undefined //这是变量声明
}
- 将实参与形参相统一,就是将实参赋值给形参 ;
// 这个函数的执行结果是什么??
AO{
a:1 //将实参1赋值给形参
b:undefined //这是变量声明
}
- 在函数体中找到函数声明,并将其作为AO的属性 ;
// 这个函数的执行结果是什么??
AO{
a:function a(){}; //找到函数声明a,并将其作为AO的属性
b:function(){} ; //找到函数声明b,并将其作为AO的属性
d:function d(){} ;//找到函数声明d,并将其作为AO的属性
}
- 执行函数 ;
// 这个函数的执行结果是什么??
function fn(a){
console.log(a); //第一步,打印a,在AO对象中找到a,也就是function a(){};
var a =123; //第二步,将123赋值给a,此时,a=123
console.log(a); //所以这一步的执行结果是123
function a(){}; //这一步已经在预编译中执行了,所以此时忽略
console.log(a); //所以这一步的执行结果还是123
var b = function(){};//这一步已经在预编译中执行了,所以此时忽略
console.log(b); //此时找到AO中的b,也就是function(){}
function d(){} ;//这一步已经在预编译中执行了,所以此时忽略
}
fn(1);
所以执行结果是:
function a(){};
123;
123;
function(){};
最后,我只想说,即使你学过很多框架、做过很多项目,如果你连最基础的js、css都记不清楚,那么,在面试中,面试官对你的能力也会提出质疑!!!
夯实基础,厚积薄发!
这篇文章是学习自渡一教育的一位老师的视频,感谢了。。。