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 -- 变量对象 #5

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

JavaScript -- 变量对象 #5

mt51 opened this issue Oct 19, 2018 · 0 comments

Comments

@mt51
Copy link
Owner

mt51 commented Oct 19, 2018

变量对象

每个执行上下文中都有三个属性:

  • 变量对象
  • 作用域
  • this

变量对象(Variable Object,VO)中保存着在当前执行上下文中声明的变量、函数和函数的形参(在函数的执行上下文中存在)。虽然在代码中不能直接访问这个对象,但是解析器在处理数据的时会在后台使用它。变量对象有两种存在方式,一种是全局上下文下的变量对象,一种是函数上下文下的变量对象。

全局上下文下的变量对象

全局对象

全局对象是预定义的对象,会在进入任何执行上下文之前创建完成,并且在程序中的任何地方都可以访问,并且是唯一的。

在全局上下文中变量对象就是全局对象。

函数上下文的变量对象

在函数上下文中,会使用活动对象(Active Object)来作为其变量对象,活动对象在最开始只包含一个变量即arguments对象。

处理上下文的两个阶段

执行上下文的代码会被分为两个阶段来处理:

  • 进入执行上下文
  • 代码执行

进入执行上下文

在进入执行上下文的时候,变量对象中会包括这些属性:

  • 函数的所有形参(在函数上下文中存在)
    1. 由名称和对应值组成的一个变量对象属性被创建
    2. 没有实参的话,名称对应的值为undefined
  • 所有的函数声明
    1. 由名称和对应值(函数对象)组成一个变量对象的属性被创建
    2. 如果变量对象存在同名的属性,则会将属性完全覆盖
  • 所有的变量声明
    1. 由名称和对应值组成一个变量对象的属性被创建
    2. 如果变量名称和已经声明的形式参数或是函数相同,变量声明你不会干扰已经存在的这类属性
// 举个例子
function test (a) {
    console.log(a) // 666
    var a = 123
    var b = 456
    function c () {}
    var d = function () {}
    console.log(a) // 123
}
test(666)

在进入执行上下文的时候,AO为:

AO = {
    arguments: {
        0: 666
    },
    a: 666,
    b: undefined,
    c:  <reference to FunctionDeclaration 'c'>,
    d: undefined
}

代码执行

在进入执行上文的时候,变量对象中已经创建了对应的属性,但大部分属性都是undefined。在代码执行阶段,才会为属性进行赋值操作。

上个例子在执行阶段进行的变换:

AO['a'] = 123
AO['b'] = 456
AO['d'] =  <reference to FunctionDeclaration>

再看另一个例子:

console.log(x)
var x = 10
console.log(x)
x = 20
function x () {}
console.log(x)

进入执行上下文:

VO = {
    x: <reference to FunctionDeclaration 'x'>,
}

代码执行阶段:

第一步执行:console.log(x)

此时变量对象中属性x的值为函数x

第二步执行:x = 10

此时,对变量对象中的属性x重新赋值

VO['x'] = 10

第三步执行:console.log(x)

此时变量对象中属性x的值为10

下面的执行和第二步第三步类似,最后打印20

我们把这个例子改造下会更容易明白

var x 
function x () {}
console.log(x)
x = 10
console.log(x)
x = 20
console.log(x)

总结

对于变量对象:

  • 在全局上下文中变量对象就是全局对象
  • 在函数上下文中变量对象初始化为Arguments对象,调用函数时,会为其创建一个Arguments对象,并自动初始化局部变量arguments,指代该Arguments对象。所有作为参数传入的值都会成为Arguments对象的数组元素
  • 在进入执行上下文时,会将形参,函数声明和变量声明作为属性值添加到变量对象中,并提供初始的属性值
  • 在代码执行过程中会变量对象会随着代码的执行变换。

参考

http://www.cnblogs.com/TomXu/archive/2012/01/16/2309728.html

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