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

JavaScript -- 执行上下文、变量对象和作用域链总结 #8

Open
mt51 opened this issue Oct 23, 2018 · 0 comments
Open

JavaScript -- 执行上下文、变量对象和作用域链总结 #8

mt51 opened this issue Oct 23, 2018 · 0 comments

Comments

@mt51
Copy link
Owner

mt51 commented Oct 23, 2018

执行上下文、变量对象和作用域链总结

了解了执行上下文、变量对象和作用域链相关的知识点,我们来重新看几个比较常见的例子。

先来看第一个例子,关于变量提升

console.log(foo)
function foo () {}
var foo = '123'

变量对象这篇文章中,提到了当进入执行上下文是,会将函数的形参、所有的函数声明、所有的变量声明以属性的形式保存到变量对象中,其中有一点是:

如果变量对象中存在与函数声明相同的属性值,则函数声明将会把该属性值完全覆盖

如果变量名称和已经声明的函数形参或者是函数相同,变量声明不会干扰到已经存在的这类属性

具体分析如下:

  • 当进入全局上下文时:
globalContext.VO = {
    foo: <reference to FunctionDeclaration 'foo'>
}
  • 当代码执行时

第一步:

console.log(foo)   // function foo () {}

第二步

foo = '123'

这是,对变量foo重新赋值,变量对象会随着变换,此时变量对象如下:

globalContext.VO = {
    foo: '123'
}

第二个例子,关于作用域链

var scope = 'global scope'
function checkScope () {
    var scope = 'inner scope'
    console.log(scope)
}
checkScope()

1、进入全局执行上下文,创建变量对象VO

VO = globalContext = {
    scope: undefined,
    checkScope: <reference to FunctionDeclaration 'checkScope' >
}

此时的作用域为:

globalScope = [VO]

2、给变量scope赋值,此时VO会随之变化

VO.scope = 'global scope'

3、创建函数checkScope,此时会将当前所在的执行上下文环境VO保存在checkScope[[Scope]]内部属性中

checkScope.[[Scope]] = [VO]

4、调用函数checkScope,创建执行上下文,首先取到checkScope.[[Scope]]来构建checkScope的作用域链FunctionScope

FunctionScope = [checkScope.[[Scope]]] = [VO]

5、随后,创建活动对象AO,

checkScopeContext.[AO] = {
    scope: undefined
}

6、活动对象创建完成之后,推入函数作用域链中,此时checkScope的作用域链为

FunctionScope = [AO, VO]

7、执行函数checkScope内部代码,为scope赋值,活动对象随之变化

checkScopeContext.[AO].scope = 'inner scope'

此时,此时checkScope的作用域为

FunctionScope = [AO, VO] = [
    {
        scope: 'inner scope'
    },
    {
        scope: 'global scope',
        checkScope: <reference to FunctionDeclaration 'checkScope' >
    }
]

最终,输入的值是

console.log(scope)  // 'inner scope'
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