1. 程式人生 > >變量對象VO與活動對象AO

變量對象VO與活動對象AO

post 內部 函數表達式 callee 上下 函數的參數 數值 內容 包含

變量對象VO

變量對象VO是與執行上下文相關的特殊對象,用來存儲上下文的函數聲明,函數形參和變量。在global全局上下文中,變量對象也是全局對象自身,在函數上下文中,變量對象被表示為活動對象AO。

變量對象VO存儲上下文中聲明的以下內容
{
函數聲明FD(如果在函數上下文中),—-不包含函數表達式
函數形參function arguments,
變量聲明–註意b=10不是變量,但是var b = 10;是變量,有變量聲明提升

var a = 10;

function test(x) {
  var b = 20;
};

test(30);

// 全局上下文的變量對象
VO(globalContext) = {
  a: 10,
  test: <reference to function>
};

// test函數上下文的變量對象
VO(test functionContext) = {
  x: 30,
  b: 20
};

  變量對象VO分類

全局上下文的變量對象VO,函數上下文的變量對象VO

//全局上下文的變量對象VO就是全局對象

VO(globalContext) === global;

  活動變量AO

當函數被調用後,這個特殊的活動對象就被創建了。它包含普通參數與特殊參數對象(具有索引屬性的參數映射表)。活動對象在函數上下文中作為變量對象使用。

在函數執行上下文中,VO是不能直接訪問的,此時由活動對象(activation object,縮寫為AO)扮演VO的角色

VO(functionContext) === AO;

Arguments對象是活動對象的一個屬性,它包括如下屬性:

callee — 指向當前函數的引用

length — 真正傳遞的參數個數

properties-indexes (字符串類型的整數) 屬性的值就是函數的參數值(按參數列表從左到右排列)。
properties-indexes內部元素的個數等於arguments.length. properties-indexes 的值和實際傳遞進來的參數之間是共享的。

技術分享圖片
function foo(x, y, z) {
    
     console.log(foo.name); //foo
  // 聲明的函數參數數量arguments (x, y, z)
  console.log(foo.length); // 3

  // 真正傳進來的參數個數(only x, y)
console.log(arguments.length); // 2 // 參數的callee是函數自身 console.log(arguments.callee === foo); // true // 參數共享 console.log(x === arguments[0]); // true console.log(x); // 10 arguments[0] = 20; console.log(x); // 20 x = 30; console.log(arguments[0]); // 30 // 不過,沒有傳進來的參數z,和參數的第3個索引值是不共享的 z = 40; console.log(arguments[2]); // undefined arguments[2] = 50; console.log(z); // 40 } foo(10, 20);
View Code

處理上下文代碼的2個階段

進入執行上下文和執行代碼

進入執行上下文:
變量是進入上下文階段放入VO中,也就是變量聲明提升並且變量聲明順序上是在函數聲明和形參聲明後

//變量聲明在順序上跟在函數聲明和形式參數聲明之後,而且在這個進入上下文階段,變量聲明不會幹擾VO中已經存在的同名函數聲明或形式參數聲明
alert(x); // function

var x = 10;
alert(x); // 10

x = 20;

function x() {};

alert(x); // 20

  

alert(x); // 20

var x = 10;
alert(x); // 10

x = 20;

function b(x) {};

alert(x); // 20

  

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

test(10); // call
當進入帶有參數10的test函數上下文時,AO表現為如下:
//AO裏並不包含函數“x”。這是因為“x” 是一個函數表達式(FunctionExpression, 縮寫為 FE) 而不是函數聲明,函數表達式不會影響VO
AO(test) = {
  a: 10,
  b: undefined,
  c: undefined,
  d: <reference to FunctionDeclaration "d">
  e: undefined
};

  

//函數表達式不在AO中
console.log(x)  // x is not defined
 (function x() {});

  

變量對象VO與活動對象AO