Hibop.github.io icon indicating copy to clipboard operation
Hibop.github.io copied to clipboard

关于js引擎工作原理

Open Hibop opened this issue 6 years ago • 0 comments

var x = 1; // 定义一个全局变量 x
function foo(y) {
  var x = 2; // 定义一个局部变量 x
  function bar(z) { // 定义一个内部函数 B
    console.log(x + y + z);
  }
  return bar; // 返回函数B的引用
}
var baz = foo(1); // 执行A,返回B
baz(1); // 执行函数B,输出 4

ECStack: 执行上下文栈 Execution Context Stack
EC: 执行上下文
VO: 变量对象(Varibale Object)
AO: 活动对象(Activation Object)
scopeChain: 作用域链(Scope Chain)

ECStack = [ //执行环境栈
  EC(bar) = {   //创建bar的执行环境,并处于作用域链的顶端
      [scope]:AO(foo), //指向函数A的作用域链,AO(A)->VO(G)
      var AO(bar) = { //创建函数bar的活动对象
          z:1,
          arguments:[],
          this: window
      }
      scopeChain:<AO(bar), bar[[scope]]>  //链表初始化为B[[scope]],再将AO(B)加入链表表头,此时B的作用域链:AO(B)->AO(A)-VO(G)
  },
  EC(foo)) = { // foo的执行环境
    [scope]: VO(G), //VO是全局变量对象
    AO(foo): { //创建函数A的活动对象
      y: 1,
      x: 2, //定义局部变量x
      bar: function () {
        ...
      }, //定义函数B
      bar[[scope]] = this; // this指代AO本身,而AO位于scopeChain的顶端,因此B[[scope]]指向整个作用域链
      arguments: [], //平时我们在函数中访问的arguments就是AO中的arguments
      this: window //函数中的this指向调用者window对象
    },
    scopeChain: < AO(foo), foo[[scope]] > //链表初始化为A[[scope]],然后再把AO加入该作用域链的顶端,此时A的作用域链:AO(A)->VO(G)
  },
  EC(G) = { //全局执行环境
    VO(G): { //创建全局变量对象
      ... //包含全局对象原有的属性
      x = 1; //定义变量x
      foo = function () {
        ...
      }; //定义函数A
      foo[[scope]] = this; //定义A的scope,A[[scope]] == VO(G)
    }
  }
];

参考文献 https://www.cnblogs.com/onepixel/p/5090799.html https://juejin.im/post/5c6bbf0f6fb9a049ba4224fd

Hibop avatar Aug 08 '19 06:08 Hibop