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

作用域和闭包 #8

Open
Genluo opened this issue Aug 31, 2019 · 2 comments
Open

作用域和闭包 #8

Genluo opened this issue Aug 31, 2019 · 2 comments

Comments

@Genluo
Copy link
Owner

Genluo commented Aug 31, 2019

作用域和作用域链

在Javascript中采用的是词法作用域,和词法作用域相对的是动态作用域,词法作用域是在函数定义的时候就确定了,动态作用域是在函数调用的时候才确定的。当我们创建一个函数时候,函数内部属性[[scope]]就跟根据当前词法作用域生成作用域,注意这并不是作用域链,作用域是函数上下文中的内容,那么函数上下文是如何创建的?当函数执行的时候,将会构建函数上下文,函数上下文存在三个重要的属性,一个是AO活动对象,一个是[[scope]]作用域链,一个是this,那么如何构建函数的作用域链,就是上下文中的AO活动对象和函数的作用域连接就形成一个新的作用域链条,到这个时候,完整的作用域就会创建完成。比如下面这个例子:

function foo() {
    function bar() {
        ...
    }
}
// 创建时候生成的scope
foo.[[scope]] = [
  globalContext.VO
];

bar.[[scope]] = [
    fooContext.AO,
    globalContext.VO
];

Activetion Object(AO) 活动对象、Variable Object(VO)变量对象

这里面存在两个问题:

  • 为什么至于为什么会有两个作用域链?

是因为在函数创建的时候并不能确定最终的作用域的样子

  • 为什么会采用复制的方式而不是直接修改呢?

应该是因为函数会被调用很多次吧。

  • 这里面函数的AO和VO有什么区别

其实活动对象(AO)和变量对象(VO)其实是一个东西,只是变量对象是规范上的或者说是引擎实现上的,活动对象不可在 JavaScript 环境中访问,只有到当进入一个执行上下文中,这个执行上下文的变量对象才会被激活,所以才叫 activation object ,而只有被激活的变量对象,也就是活动对象上的各种属性才能被访问。

  • 函数有作用域链吗?

函数是没有作用域链的,函数中只存在根据词法作用域生成的作用域,只有函数上下文对象才有作用域链的概念。参考深入理解作用域链

闭包的原理

感谢@冴羽的博文,下面说下闭包吧,当理解函数建立原型链的过程就会很容易理解为什么会产生闭包,根据js垃圾回收机制,如果一个函数被return,那个这个函数的作用域将会有一个指向父函数活动对象的指针,导致父函数的活动对象在父函数执行完成之后不能被回收。并且子函数可以通过作用域链一直进行访问,这就是原因。

@Genluo
Copy link
Owner Author

Genluo commented Sep 1, 2019

为什么至于为什么会有两个作用域链?

  • 是因为在函数创建的时候并不能确定最终的作用域的样子

这个回复是有问题的,应该是只有一个函数作用域链,函数执行时会生成函数上下文,函数上下文中才有这个作用域链

  • 为什么会采用复制的方式而不是直接修改呢?
    应该是因为函数会被调用很多次吧。

并不明白其意思

@Genluo
Copy link
Owner Author

Genluo commented Sep 1, 2019

创建的函数会生成完整的函数作用域,函数执行时,会将当前函数的活动对象和函数作用域进行连接,形成函数作用域链

铭记一点:函数执行的时候才会生成函数上下文,所有函数上下文并不能被赋值,这个函数上下文只是V8引擎使用的变量对象

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

No branches or pull requests

1 participant