JavaScript预编译与执行期上下文

JavaScript运行三部曲

Step1:语法分析
Step2:预编译
Step3:解释执行

今天着重介绍一下预编译的过程,在开始正式介绍预编译之前,还要补充两个小知识:
一个是:暗示全局变量 imply global
这个是说 任何变量,如果未经声明就赋值次变量就归全局所有

a = 123;  // 这是一个未经声明就赋值的变量;
console.log(a);

我们执行这个代码块的时候,发现不会报错,并且a 可以正常访问~

通过window访问也可以找到a

JavaScript预编译与执行期上下文
JavaScript预编译与执行期上下文

再来看这样一个函数

function test() {
    var a = b = 123;
}
test();
JavaScript预编译与执行期上下文

在全局上b是可以找到的,因为b是未经声明就赋值的变量

第二个小知识是: 一切声明的全局变量,全是window的属性
换一种方式理解可以认为 window就是全局的域,我们在定义一个全局变量的时候 ,会存放在window中,当我们需要用到这个变量的时候会到window中寻找

//现在我要定义一个全局变量
var a = 123;
//此时,JavaScript为我们开辟了一个空间叫:window
/*
window{
	a :123;
}
就像这样一个空间,存放了我们的变量,需要用的时候从这里来拿
*/

补充完之后,正式进入预编译的环节,我们经常可以听到一句关于预编译的话:【变量 声明提升, 函数声明 整体提升】,其实这句话只是涵盖了预编译的一部分而已
其实,纵观整个预编译过程(发生在函数执行前一刻),总共要分四个步骤

  1. 创建AO对象
  2. 寻找形参和变量声明,把形参和变量声明作为AO对象的属性名,同时赋值为undefined
  3. 将实参值和形参值相互统一起来
  4. 在函数体里找函数声明(并非函数表达式)作为属性名(当然已经存在的就不用再次作为属性名啦) ,并把这个函数体整体赋给它。

举个小栗子:

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{
    //第二步:找形参和变量声明
    a: undefined;
    b: undefined;
}
//第三步: 将实参和形参统一
//此时AO变为如下形式
AO{
    a:1;
    b: undefined;
}
//第四步:找函数声明
//此时AO变为如下形式
AO{
    a: function a() { };
    b: undefined;
    d: function d() { };
}
//至此,AO对象创建完毕~~
//现在轮到我们来看每一条的输出是什么

此时万事俱备,开始执行,首先运行到第一条输出
此时我们在AO中查看,此时应该打印 function a(){};
运行到第二条语句:var a = 123;
此时AO发生变化

AO{
    a: 123;
    b: undefined;
    d: function d() { };
}

运行到第三条语句:
在AO中查看 发现 a:123
所以打印 123;

运行到第四条语句:function a(){} 这条语句在预编译的过程中已经被提升上去了,所以不用管啦!
运行到第五条语句:要求我们打印a
此时AO中的 a 依旧为123;
所以打印 123;
运行到第六条语句:var b = function(){}
此时AO发生变化

AO{
    a: 123;
    b: function() { };
    d: function d() { };
}

运行到第七条语句,要求我们打印b
此时AO中 b 为function(){}
所以打印 function(){}

至此,最终答案为:

function a() { };
123;
123;
function() { }

运行结果如下:

JavaScript预编译与执行期上下文

小伙伴们,你们做对了吗?

原文出处:CSDN【Coder小何】

原文链接:https://blog.csdn.net/qq_43377853/article/details/107688617

本文观点不代表 .Net中文网 立场,转载请联系原作者。

发表评论

登录后才能评论