JavaScript预编译(执行期上下文)总结
上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
function test(a,b){
console.log(a);
var a = 'demo';
console.log(a);
function a(){}
console.log(a);
var a = function (){}
console.log(a);
console.log(b)
var b = 1;
}
test(1);
</script>
</body>
</html>
预编译(‘执行期上下文’)
预编译发生在函数执行之前
。
这句话很重要,函数执行之前也就是在这段程序开始之前,浏览器对马上要执行的函数进行预编译!!
预编译四部曲
- 创建AO对象
- 找形参和变量声明,将变量和形参作为AO属性名,值为undefined
- 将实参和形参相统一
- 在函数体里找到函数声明,值赋予函数体
- 最后程序输出变量值的时候,就是从AO对象中拿。
以上一个问题为例。以下过程都是在系统内部完成的
1、创建AO对象
var AO = {
}
2、找形参和变量声明,将变量和形参作为AO属性名,值为undefined
这里的形参首先出现的是a,b。变量为a,b。
var AO = {
a = undefined;
b = undefined;
}
3、将实参和形参相统一
这里的实参只有一个是1。
var AO = {
a =1;
b = undefined;
}
4、在函数体里找到函数声明,值赋予函数体
这里只有第十三行是函数声明,第十五行不是。
var AO = {
a = function a(){};
b = undefined;
}
5、系统执行程序(解释一行执行一行)
- console.log(a),输出a。这是输出的值为function a(){};
- var a = ‘demo’ 其实就是a = ‘demo’。因为var a已经在预编译中ok了。AO中的a的值变为’demo’;
- console.log(a) ,这时候输出的就是 demo;
- function a(){} 在预编译中已经用过了就不用了。
- console.log(a) , 输出 demo ;
- var a = function (){} AO中的a的值变为function (){};
- console.log(a),输出 function (){};
- console.log(b) b中的值一直未undefined ;输出 undefined;
- var b = 1; 将AO对象中的b的值变为1;
这样就完美解释了代码是怎样的执行循序