Open hzzzzzzzq opened 2 years ago
在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。
对于执行上下文,都有三个重要属性:
我们先来介绍一下变量对象。
变量对象是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明。
然而,由于不同执行上下文的变量对象都存在不同,所以今天我们分不同模块来聊一下不同的变量对象。
全局上下文的变量对象
函数上下文的变量对象
全局上下文中的变量对象就是全局对象。全局变量是在所有作用域都可访问的变量,与之对应的是局部变量
全局对象预定义的对象,作为 JavaScript 的全局函数和全局属性的占位符。通过使用全局对象,可以访问所有其他。
this
Window
console.log(this); // window 对象
Object
console.log(this instanceof Obejct); // true
Math
console.log(Math.pow(2, 2)); // 4
var a = 1; console.log(this.a); // 1
window
var a = 1; console.log(window.a); // 1 this.window.b = 2; console.log(this.b); // 2
函数上下文中,VO 时不能直接访问的,所以用活动对象(Activation Object,OA)来表示变量对象。 但是其实是一个东西,只不过在变量对象的规范上来说,是有区别的。 AO 是在进入函数上下文时才被创建的,它通过 arguments 属性来初始化。arguments 属性就是 Argumens 对象。
VO
Activation Object,OA
AO
arguments
Argumens
Arguments 对象是 AO 对象的一个属性,它包括如下属性:
Arguments
callee
length
arguments[@@iterator]
执行上下文,会分为两个阶段,分析阶段和执行阶段。
当进入分析阶段时,这时候还没有执行代码。
变量对象包括:
函数的所有形参 (如果是函数上下文) 由名称和对应值组成的一个变量对象的属性被创建,属性值为 undefined
函数声明 由名称和对应值(函数对象)组成一个变量对象的属性被创建,如果变量对象已经存在相同名称的属性,则完全替换这个属性
变量声明
undefined
我们来举个例子
function fn(age) { var name = 'hzzzzzzzq'; function fn2() {} var fn3 = function () {}; // 其实也算是一个变量 name = 'hzq'; } fn(18);
我们来看看进入执行上下文的分析阶段的 AO 是
AO = { // 函数的形参 arguments: { 0: 1, length: 1, }, age: 18, name: undefined, // 变量声明 fn2: reference to function fn2() {}, // 函数声明 fn3: undefined // 变量声明 };
在代码执行阶段中,会顺序来执行代码,根据代码,修改变量对象的值。
我们将上面的代码执行完毕后,来看看 AO :
AO = { arguments: { 0: 1, length: 1, }, age: 18, name: 'hzq', fn2: reference to function fun2() {}, fn3: reference to FunctionExpression "fn3" };
其实到目前为止,我们的介绍已经结束了。但是肯定不过瘾,或许还不太懂,所以我们...
再来看个例子吧。
function fn1() { console.log(x); x = 1; } fn1(); function fn2() { x = 1; console.log(x); } fn1();
可以来看看上面的代码,打印的是什么呢? 第一个打印 Uncaught ReferenceError: x is not defined 第二个打印 1
Uncaught ReferenceError: x is not defined
1
这又是为什么呢?
第一个例子中,我们来看看执行上下文时的 AO,因为我们在创建时 AO 对象中没有找到 x 变量,并且往全局变量中找也没有找到,所以报错。
x
AO = { arguments: { length: 0, }, };
第二个例子中,我们来看看执行上下文时的 AO,我们在创建时找到了 x,所以会打印结果。
AO = { arguments: { length: 0, }, x: 1, };
JavaScript 深入之变量对象
在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。
对于执行上下文,都有三个重要属性:
我们先来介绍一下变量对象。
变量对象
变量对象是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明。
然而,由于不同执行上下文的变量对象都存在不同,所以今天我们分不同模块来聊一下不同的变量对象。
全局上下文的变量对象
函数上下文的变量对象
全局对象
全局上下文中的变量对象就是全局对象。全局变量是在所有作用域都可访问的变量,与之对应的是局部变量
this
引用,在客户端中,全局对象就是Window
对象,可以通过浏览器查看。Object
构造函数实例化的一个对象。Math
的一些方法。window
属性指向自身函数上下文
函数上下文中,
VO
时不能直接访问的,所以用活动对象(Activation Object,OA
)来表示变量对象。 但是其实是一个东西,只不过在变量对象的规范上来说,是有区别的。AO
是在进入函数上下文时才被创建的,它通过arguments
属性来初始化。arguments
属性就是Argumens
对象。Arguments
对象是AO
对象的一个属性,它包括如下属性:callee
- 指向参数所属的当前执行的函数,指向调用当前函数的函数length
- 传递给函数的参数数量arguments[@@iterator]
- 返回一个新的 Array 迭代器对象,该对象包含参数中每个索引的值执行过程
执行上下文,会分为两个阶段,分析阶段和执行阶段。
分析阶段
当进入分析阶段时,这时候还没有执行代码。
变量对象包括:
函数的所有形参 (如果是函数上下文) 由名称和对应值组成的一个变量对象的属性被创建,属性值为 undefined
函数声明 由名称和对应值(函数对象)组成一个变量对象的属性被创建,如果变量对象已经存在相同名称的属性,则完全替换这个属性
变量声明
undefined
)组成一个变量对象的属性被创建我们来举个例子
我们来看看进入执行上下文的分析阶段的 AO 是
执行阶段
在代码执行阶段中,会顺序来执行代码,根据代码,修改变量对象的值。
我们将上面的代码执行完毕后,来看看 AO :
其实到目前为止,我们的介绍已经结束了。但是肯定不过瘾,或许还不太懂,所以我们...
再来个例子
再来看个例子吧。
可以来看看上面的代码,打印的是什么呢? 第一个打印
Uncaught ReferenceError: x is not defined
第二个打印1
这又是为什么呢?
第一个例子中,我们来看看执行上下文时的
AO
,因为我们在创建时AO
对象中没有找到x
变量,并且往全局变量中找也没有找到,所以报错。第二个例子中,我们来看看执行上下文时的
AO
,我们在创建时找到了x
,所以会打印结果。