JavaScript 的可执行代码,具备执行上下文,而每一个上下文包括如下 3 个属性:javascript
变量对象提供了当前环境所需的变量和函数
做用域链用于保证 JS 中变量和函数有序地访问
this 为函数提供了执行者对象java
一个上下文的执行周期能够用下图示意:
express
本文就来介绍执行上下文中的变量对象
。数组
那什么是变量对象呢?先看定义:浏览器
变量对象是与执行上下文相关的数据做用域,用于存储执行上下文中的变量和函数声明。bash
不一样的执行上下文,变量对象会有一些差异。接下来就分别针对不一样的上下文讨论其区别。闭包
全局对象(Global object) 是在进入任何执行上下文以前就已经建立了的对象; 这个对象只存在一份,它的属性在程序中任何地方均可以访问,全局对象的生命周期终止于程序退出那一刻。app
在全局代码的上下文执行环境中,变量对象就是全局对象,在浏览器中,就是 window 对象。函数
此时,咱们能够用 this 和 self 来访问到全局对象,也就是它自己post
console.log(this) // window
console.log(self) // window
复制代码
其次,全局对象初始建立阶段将 Math、String、Date、parseInt 等函数做为自身方法,还会把全局变量做为本身的属性。
用伪代码表示就是:
global = {
Math: <...> Date: <...> window: global // 引用自身 } 复制代码
咱们已经知道,变量对象存储量执行上下文中的函数声明和变量,在函数上下文中,多了arguments(函数参数列表)
, 一个类数组对象。
用伪代码来表示:
VO = {
arguments: Arguments,
variables: undefine,
functionName: <Function reference>
}
复制代码
函数未进入执行阶段以前,变量对象中的属性都不能访问!可是进入执行阶段以后,变量对象转变为了活动对象(activation object)。
因此,在函数上下文中,咱们将活动对象(activation object)做为变量对象,活动对象最开始只包含一个变量就是 arguments 对象(这个对象是全局环境中没有的)。
arguments 的属性值 Arguments 它包括以下属性:
咱们再一次来看这个过程图:
建立阶段
全局对象初始化的时候,就将变量对象引用了自身。 而函数的建立却有须要注意的地方。
函数在建立阶段就建立了变量对象
其中,变量对象包括:
进入执行上下文时,函数声明和变量声明都会提早,这就是声明提高,可是变量声明的值都是undefined,而函数声明的变量已经能够指向函数。变量声明的优先级最低。
看下面这段代码:
function foo(a, b) {
var c = 10;
function d() {}
var e = function _e() {};
(function x() {});
}
foo(10);
复制代码
当进入函数 foo 时,其变量对象的表现形式为:
VO = {
arguments: {
0: 10,
1: undefined,
length: 1
}
c: undefined,
d: <function reference to d>, e: undefined, } 复制代码
x 是函数表达式,因此不在变量对象当中,e 变量引用的值也是函数表达式,因此变量 e 自己是声明,因此在变量对象当中。
执行阶段
当前进入执行阶段,变量对象激活成活动对象,函数会顺序执行代码,改变变量对象的值:
以上代码就变成:
AO = {
arguments: {
0: 10,
1: undefined,
length: 1
}
c: 10,
d: <reference to function declaration d>,
e: <reference to Function expression to _e>,
}
复制代码
接下来看一段代码:
console.log(foo);
function foo() {
console.log("123")
}
var foo = "456";
复制代码
以上会打印函数,是由于:
变量优先处理函数声明,再是变量声明。
再看一段代码:
if (true) {
var a = 1;
} else {
var b = 2;
}
console.log(a); // 1
console.log(b); // undefined
复制代码
虽然 else 中的代码永远不会被执行,可是 b 的变量声明在执行以前就默认被设置成 undefined了。
执行上下文包括三个属性,变量对象,做用域链,this, 不一样的执行上下文,变量对象是有区别的。
全局上下文中,变量对象就是自己。
函数上下文中,变量对象包括:arguments, 函数声明,变量声明。在函数建立阶段,变量对象有默认值,进入执行阶段后,变量对象会被激活成活动对象,而后变量对象的值被顺序改变。
欢迎关注个人我的公众号“谢南波”,专一分享原创文章。