13、预编译

execution context

  • GO AO 都属于 execution context,是在函数执行期前一刻生成的。包含函数的变量声明、函数声明等。
  • 在函数执行期间,如果产生赋值等操作依旧会执行期上下文里的值产生影响。

GO

  • global execution context
  • 存储 this--window window--object document--object 及其他初始值和引用值

AO

  • function or constructor function execution context
  • function() AO 存储 this--window arguments--[] 及其他初始值和引用值
  • new Function() AO 存储 this--{} arguments--[] 及其他初始值和引用值

编译的前置条件

  • 函数只有执行前才会进行编译
  • 函数如果只有定义,没有执行,函数体内的变量不会对外界产生影响。

编译步骤

  • 寻找变量声明和参数定义
  • 实参赋值给形参
  • 寻找函数声明,并赋值函数体
  • 函数执行赋值

es5 不允许在{}块级作用域中声明函数。但es5浏览器为了兼容旧的代码没有遵循这一规定,在{}中依旧可以声明函数并提升函数体至全局或函数作用域顶部。

补充

  • 如果函数内声明了与全局变量名字相同的变量,全局变量对函数内的变量不会产生影响。如下:
  • 声明变量时,如果未使用var声明变量,如直接a = 1,则a不存在变量提升。
  • if &&等逻辑判断不会阻断预编译上下文。如下:
  • return 语句为表达式,相当于赋值语句,不参与预编译的变量提升。
  // 示例1:
      function a(){
        console.log(b);
        return function b(){} // 相当于函数表达式 x = function b(){}
      }

      var bb = a();
      bb(); // 报错,b is not defined

  // 示例2:和题目关系不大,此处说明闭包的问题,多个闭包拥有的是同一份环境的AO。
      function a(){
        var a = 1;
        return a = function(){
          console.log(a);
          a = 2;
        }
      }

      var bb = a();
      bb(); // function(){}
      bb(); // 2
  • 函数执行时,如果有全局变量,会把全局变量及变量的值一起挂载到全局中。但是函数编译时,不会对全局变量产生影响。如下:

actual combat

  • 分析下面程序的GO、AO及打印正确的结果
a = 1;
function test(e){
  function e(){}
  arguments[0] = 2;
  console.log(e);
  if(a){
    var b = 3;
  }
  var c;
  a = 4;
  var a;
  console.log(b);
  f = 5;
  console.log(c);
  console.log(a);
}
var a;
test(1);

//分析过程
GO = {
  a: undefined,
     1,
}
AO = {
  b: undefined,
  c: undefined,
  a: undefined,
      4,
  e: undefined,
      1,
      function e(){},
      2,
}
//执行结果 2  undefined  undefined 4
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容