预编译与执行上下文

今天在看腾讯课堂,姬成老师的课程,关于预编译和执行上下文讲解的特别详细。让我明白之前一直迷惑的执行上下文顺序。

这点也是面试的时候经常遇到的面试题。

预编译:发生在函数执行的前一刻,局部声明的时候。

预编译过程:

  1、创建AO对象;

  2、找形参和变量声明,将变量和形参作为AO对象的属性名,值为undefined;

  3、将实参和形参统一;

  4、在函数体里面找函数声明,值赋予函数体。

例子:

  function fn(a) {
    console.log(a);
    var a = 123;
    console.log(a);
    function a() { };
    console.log(a);
    var b = function () { };
    console.log(b);
    function d() { };
  }

  fn(1);

解析过程:

第一步:创建AO对象:

AO:{
}

第二步:找形参和变量声明,将变量和形参作为AO对象的属性名,值为undefined;

  AO : {
    a: undefined,
    b: undefined,
  }

第三步:将实参和形参统一

  AO : {
    a: 1,
    b: undefined,
  }

第四部:在函数体里面找函数声明,值赋予函数体

AO : {
    a: function a() { },
    b: undefined,
    d: function d() { },
  }

然后开始解析对象,执行上下文:(已经解析的在执行过程中忽略)

  function fn(a) {
    console.log(a);  // 取AO对象里面的a: function a() { }
    var a = 123;     // 将AO对象里面的a重新赋值,为123;
    console.log(a); // 取AO对象里面的a   123
    function a() { };  // 忽略
    console.log(a);  // 123
    var b = function () { };  // 将AO对象里面的b重新赋值为 function b() {}
    console.log(b);   // 取AO对象里面的b  为function(){ }
    function d() { }; 
  }

  fn(1); 

所有的执行上下文的顺序都可以按照这4个步骤进行分步解析。

全局声明:

全局声明的话,声明的是GO对象,GO对象也就是我们说的window;

1、声明GO对象;

2、将参数值赋值给GO对象值。

3、执行

例子:

  var global = 100;
  function fn(){
    console.log(global);
  }

  fn();

解析:

第一步:创建GO对象

GO:{

}

第二步:将值赋予给GO对象

  GO:{
    global: undefined,
    fn: funciton(){ ... }
  }

全局变量和局部变量都存在同一个变量值的话,取局部变量;

例子:

  global = 100;
  function fn(){
    console.log(global);
    global = 200;
    console.log(global);
    var global = 300; 
  }

  fn();
  var global;

解析:

第一步,全局设置了 var global,则变量提升

GO : {
  global: undefined,
  fn: funciton() { ... }
}

第二步:fn则存在局部变量,则生成AO对象

AO : {
    global : undefined,  
}

第三步: 开始解析

  global = 100;
  function fn(){
    console.log(global);  // AO对象里面含有global,则取AO对象里面的undefined
    global = 200;     // 将AO对象里面的global赋值为200
    console.log(global);  // 取AO对象里面的global, 为200
    var global = 300; 
  }
fn();
var global;
原文地址:https://www.cnblogs.com/liumcb/p/15234323.html