Skip to content

Latest commit

 

History

History
48 lines (33 loc) · 2.56 KB

作用域,作用域链.md

File metadata and controls

48 lines (33 loc) · 2.56 KB

作用域,作用域链

每个javascript函数都是一个对象,有着自己的属性,有些是我们可以访问到的,有些只供javascript引擎存取,例如[[scope]].[[scope]]就是我们常说的作用域,存储了执行期上下文的集合,所有的执行期上下文呈链式连接,也就是作用域链

作用域:每当函数执行前一刻都会生成一个自己的内部环境,也就是作用域,每次函数执行时生成的作用域都是独一无二的,当函数执行完毕后这个环境就会被销毁

<script>
	function a(){
        var b = 1;
	}
	a();
<script>

看着一段简单的代码,a函数被定义在全局里面,当a函数被定义时他会生成一个GO对象(Global Object),里面存储了全局的执行期上下文,放在a函数作用域链的顶端.

当a函数执行时,又会生成一个AO对象(ActivationObject),里面存储着a内部的执行期上下文,放在作用域链的顶端。层层递进,从而形成了作用域链,当函数执行时,就会沿着作用域链的顶端寻找他所需要的信息。

function a(){
    var b = 1;
    function c(){
        b = 2;
    }
    c();
    console.log(b);
}
a();

来看这一段,先分析一下他们的作用域链,a函数定义时生成一个GO对象,放在自己作用域链的顶端,当

a函数执行时又会生成一个AO对象,AO,GO依次存放于[[scope]]中。当c函数定义时,他生成一个AO对象,里面放着时a的作用域链,当c被执行时又会生成一个自己的AO,放在作用域链的顶端,也就是:0:cAO 1:aAO 2GO,这样依次向下。这里有一个问题,c的作用域链里面存放着的aAO是否是a真正的AO呢,答案是是的,因为a只形成了一个自己的AO,c既然站在a的身体里看世界,他拿的是a的东西,自然看到的用的是a的AO,也就是说,在c函数里面修改a函数的变量会使变量值发生改变,当a再次访问这个变量时已经是修改后的值了。

这就是作用域链的基本概念与解释,归纳一下重点:

  • 函数定义时拿上级函数的AO放在作用域链顶端

  • 函数执行时生成自己的AO放在作用域链顶端

  • 函数执行是按照从上往下的顺序在自己的作用域链里面查找变量

  • 内部函数可修改外部函数的值,用的就是外部函数的AO

  • 函数每次执行完毕就会销毁一次自己的作用域链,隐式销毁,所以每当函数执行就会重新创建一次。

    当js比较复杂是当然也是遵循这个规律,只是形成的作用域链比较长