完全明白Javascript中的变量对象

1 定义

假如变量与实行高低文相干,那变量本身应当晓得它的数据存储在那里,而且晓得怎样接见。这类机制称为变量对象(variable object)。
变量对象(缩写为VO)是一个与实行高低文相干的特别对象,它存储着在高低文中声明的以下内容:

  • 变量 (var, 变量声明);
  • 函数声明 (FunctionDeclaration, 缩写为FD);
  • 函数的形参

举例来说,我们能够用一般的ECMAScript对象来示意一个变量对象:

VO = {};

就像我们所说的, VO就是实行高低文的属性(property):

activeExecutionContext = {
     VO: {
       // 高低文数据(var, FD, function arguments)
      }
};

2 全局高低文中的变量对象

全局高低文中的变量对象就是全局对象,所以我们声明的变量都是全局对象的属性。

3 函数高低文中的变量对象

函数高低文中的变量对象由运动对象(AO)饰演。

运动对象的变化与处置惩罚高低文的两个阶段密切相干。进入实行高低文和实行代码。

3.1 进入实行高低文

当进入实行高低文(代码实行之前)时,VO里已包括了以下属性:

1. 函数的一切形参(假如我们是在函数实行高低文中)
   由称号和对应值构成的一个变量对象的属性被建立;没有通报对应参数的话,那末由称号和undefined值构成的一种变量对象的属性也将被建立。
2. 一切函数声明(FunctionDeclaration, FD)
由称号和对应值(函数对象(function-object))构成一个变量对象的属性被建立;假如变量对象已存在雷同称号的属性,则完整替代这个属性。
3. 一切变量声明(var, VariableDeclaration)
   由称号和对应值(undefined)构成一个变量对象的属性被建立;假如变量称号跟已声明的形式参数或函数雷同,则变量声明不会滋扰已存在的这类属性。

也就是变量提拔和var x = undefined 不会影响形参x的值,以后挪用x指向的照样形参。

注重:进入实行高低文时,函数声明和变量声明都提早,然则变量声明的值还都是undefined,而函数声明的变量已能够指向函数。变量声明的优先级最低。
让我们看一个例子:

function test(a, b) {
  var c = 10;
  function d() {}
  var e = function _e() {};
  (function x() {});
}
  
test(10); // call

当进入带有参数10的test函数高低文时,AO表现为以下:

AO(test) = {
  a: 10,
  b: undefined,
  c: undefined,
  d: <reference to FunctionDeclaration "d">
  e: undefined
};

注重,AO里并不包括函数“x”。这是由于“x” 是一个函数表达式(FunctionExpression, 缩写为 FE) 而不是函数声明,函数表达式不会影响VO。 不管怎样,函数“_e” 一样也是函数表达式,然则就像我们下面将看到的那样,由于它分配给了变量 “e”,所以它能够经由过程称号“e”来接见。

3.2 代码实行

进入高低文阶段,AO/VO已具有了属性(不过,并非一切的属性都有值,大部份属性的值照样体系默许的初始值undefined )。
照样前面谁人例子, AO/VO在代码实行时期被修正以下:

AO['c'] = 10;
AO['e'] = <reference to FunctionExpression "_e">;

另一个典范例子:

alert(x); // function
  
var x = 10;
alert(x); // 10
  
x = 20;
  
function x() {};
  
alert(x); // 20

为何第一个alert “x” 的返回值是function,而且它照样在“x” 声明之前接见的“x” 的?为何不是10或20呢?由于,依据范例函数声明是在当进入高低文时填入的; 赞同周期,在进入高低文的时刻另有一个变量声明“x”,那末正如我们在上一个阶段所说,变量声明在递次上跟在函数声明和形式参数声明以后,而且在这个进入高低文阶段,变量声明不会滋扰VO中已存在的同名函数声明或形式参数声明,因而,在进入高低文时,VO的构造以下:

VO = {};
  
VO['x'] = <reference to FunctionDeclaration "x">
  
// 找到var x = 10;
// 假如function "x"没有已声明的话
// 这时刻"x"的值应当是undefined
// 然则这个case里变量声明没有影响同名的function的值
  
VO['x'] = <the value is not disturbed, still function>
//紧接着,在实行代码阶段,VO做以下修正:
VO['x'] = 10;
VO['x'] = 20;

我们能够在第二、三个alert看到这个结果。
鄙人面的例子里我们能够再次看到,变量是在进入高低文阶段放入VO中的。(由于,虽然else部份代码永久不会实行,然则不管怎样,变量“b”依然存在于VO中。)

if (true) {
 var a = 1;
} else {
 var b = 2;
}
  
alert(a); // 1
alert(b); // undefined,不是b没有声明,而是b的值是undefined

本文绝大部份内容来自: http://dmitrysoshnikov.com/ec…
仅做少量修正

    原文作者:传播正能量
    原文地址: https://segmentfault.com/a/1190000007906723
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞