深入理解JavaScript系列学习笔记——执行上下文之代码执行

代码执行这个周期内,AO/VO已经拥有了属性(不过,并不是所有的属性都有值,大部分属性的值还是系统默认的初始值undefined )。

1.举例

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/VO在代码解释期间被修改如下:

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

再次注意,因为FunctionExpression“_e”保存到了已声明的变量“e”上,所以它仍然存在于内存中。而FunctionExpression “x”却不存在于AO/VO中,也就是说如果我们想尝试调用“x”函数,不管在函数定义之前还是之后,都会出现一个错误“x is not defined”,未保存的函数表达式只有在它自己的定义或递归中才能被调用。
另一个经典例子:

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

本文整理摘录自:汤姆大叔的博客—— 深入理解JavaScript系列(12):变量对象(Variable Object)

猜你喜欢

转载自blog.csdn.net/yangyuqingabc/article/details/80767236