Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

作用域,作用域链 #4

Open
Qhappyman opened this issue Mar 1, 2019 · 1 comment
Open

作用域,作用域链 #4

Qhappyman opened this issue Mar 1, 2019 · 1 comment

Comments

@Qhappyman
Copy link
Owner

作用域链精解

@Qhappyman
Copy link
Owner Author

作用域,作用域链

每个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比较复杂是当然也是遵循这个规律,只是形成的作用域链比较长

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant