js中的预编译和作用域链

JavaScript运行三部曲

脚本执行js引擎都做了什么呢?

  1. 语法分析
  2. 预编译
  3. 解释执行

1.语法分析分析语法是不是错了

2,在语句执行的时候会进行预编译

3.在编译完了进行语句执行

下面就是编译的主要步骤

三。预编译的过程(分四步):

1.(对函数)创建AO对象;(对全局的时候也就是Window)创建GO对象

2.找形参和变量声明,将变量名和形参名作为AO属性名,或GO对象 初始值为undefined

3.将实参值传递形参统一

4.在函数体里面找变量声明,值赋予函数体

在预编译和执行的过程会对赋值语句会对AO,GO中的变量进行覆盖,应该以执行结束后的结果为最终的变量标准。

当出现同命的时候函数为什么会覆盖变量应为函数是第4步变量是第二步就复制了,所以会函数的优先级高

下面是一个例子的全过程:

<script type="text/javascript">
		global = 100;
		function fn(){
			console.log(global); //undefined
			global = 200;
			console.log(global); //200
			var global = 300;
		}
		fn();
		var global;
	</script>
1.首先全局对象创建GO执行上下文
GO{
    2.对形参和变量声明,将其作为属性名,值为undefined
    global:undefined --执行后-->100
    3.全局对象没有形参
    4.在函数体里找函数声明,值赋予函数体
    fn:function fn(){};
}
执行全局
1. global = 100
2.fn();(先预编译fn(),在执行)

(函数预编译产生AO上下文)
AO{
 2.对形参和变量声明,将其作为属性名,值为undefined
    global:undefined --fn的AO执行到第二句-->200 --fn的AO执行到第四句-->300
 3.没形参
 4.没函数声明
}
A0执行{
    第一句:console.log(global); //undefined在AO的执行上线中global:undefined;
    第二句:global = 200;
    第三句:console.log(global); //在AO中找global已经变成了200
    第四句:global = 300; //
}

所以最后我们的
GO{
    global:100
    fn:function fn(){};
}
AO{
global:300
}

只有把这个看懂了(看懂一点也没关系)下面我们来写什么是作用域链 ,看完了什么是作用域链

函数也是一个对象在这个对象中有些我们可以访问的属性比如prototype,name,不可以访问的有[[scope]]属性

[[scope]]属性:指的就是我们所说的作用域,其中储存了运行期上下文的集合

作用域链:[[scope]]中储存的执行期上下文对象的集合,这个集合呈链式链接,也叫作用域链

下面看一个例子

function a(){
    function b(){
        var b = 234;
}
    var a= 123;
    b();
}
var glob = 100;
a();

      

在b定义的时候a马上快执行完的时候的图像

首先b会继承了aAO和GO

在b自己执行的时候会变成(图二)

scope chain中的数值代表数值的key,key代表:

0 ---自己的AO(Activation Object)

1---b的AO

2---GO(Clobal Object)

因为这样才会出现说b找不到的变量可以到a中找,但a不到以到b中找都是因为这个(作用域链)的原因

子 - 父 -祖宗--全局 这样一个(作用域链)的过程;

猜你喜欢

转载自blog.csdn.net/qq_39148344/article/details/83929131