JS预编译

在JavaScript中存在一种预编译的机制,这也是Java等一些语言中没有的特性,也就正是因为这个预编译的机制,导致了js中变量提升的一些问题,下面这两句话能解决开发当中一部份问题,但不能解决所有问题,还有一些问题是你必须通过学习预编译才能解决的。

预编译分为全局预编译和局部预编译,全局预编译发生在页面加载完成时执行,而局部预编译发生在函数执行的前一刻。

js运行三部曲:
    语法分析
    预编译
    解释执行

函数声明整体提升:把函数声明提在最前面
变量 声明提升:会把声明提升到最前面 (var a)

1.imply global暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有
全局对象是window
eg:a = 123;
eg:var a = b = 123;
2.一切声明的全局变量,全是window的属性
eg:var a = 123; ==> window.a = 123

预编译发生在函数执行的前一刻
预编译:
四部曲:
    1.创建AO 对象 (Activation Object,执行器上下文)
    2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
    3.将实参值和形参统一
    4.在函数体里面找函数声明,值赋予函数体

    eg: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);

步骤: 

    1.AO
    2.AO{
        a:undefined,
        b:undefined
    }
    3.AO{
        a:1,
        b:undefined
    }
    4.AO{
        a:function a() {},
        b:undefined,
        d:function d() {}
    }

    输出结果:function a() {}
             123
             123
             function () {}
    
    eg2:function test(a,b) {
        console.log(a);
        c = 0;
        var c;
        a = 3;
        b = 2;
        console.log(b);
        function b () {}
        function d () {}
        console.log(b);
    }
    test(1)

步骤: 

    1.AO
    2.AO{
        a:undefined,
        b:undefined,
        c:undefined,
    }
    3.AO{
        a:1,
        b:undefined,
        c:undefined,
    }
    4.AO{
        a:1,
        b:function b() {}
        c:undefined
        d:function d() {}
    }
    输出结果为1,2,2

全局:1.生成一个GO对象Global Object
     2.GO{

     }
     找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
     3.在函数体里面找函数声明,值赋予函数体
     
     GO === window
     
     eg:
     var a = 123;
     function fn(a) {
         console.log(a);
     }
     fn();
     全局生成GO
     GO{
         a:undefined;
         fn:undefined
     }
     GO{
         a:123,
         fn:function fn(){...}
     }
     此时执行fn(),局部生成AO
     AO{
         
     }
     因为AO里没有东西,所以console.log(a)回向GO中去找,输出为123

eg:
1.function bar() {
    return foo;
    foo = 10;
    function foo() {}
    var foo = 11;
}
console.log(bar());

2.console.log(bar());
  function bar() {
      foo = 10;
      function foo(){}
      var foo = 11;
      return foo;
  }


eg:
    a = 100;
    function demo(e) {
        function e() {}
        arguments[0] = 2;
        console.log(e);
        if(a) {
            var b = 123;
            function c() {}
        }
        var c;
        a = 10;
        var a;
        console.log(b);
        f = 123;
        console.log(c);
        console.log(a);
    }
    var a;
    demo(1);
    console.log(a);
    console.log(f);
    步骤:
    GO{
        a:100,
        demo:function() {},
    }
    执行demo(1),执行demo函数
    AO{
        e:undefined,
        b:undefined,
        c:undefined,
        a:undefined
    }
    AO{
        e:1,
        b:undefined,
        c:undefined,
        a:undefined
    }
    AO{
        e:2,
        b:undefined,
        c:undefined,(现在规定if里不能定义函数,所以不是function)
        a:10
    }
    函数里的console.log(e):2
            console.log(b):undefined
            console.log(c):undefined
            console.log(a):10
    GO{
        a:100,
        demo:function() {}
        f:123
    }
    函数外的console.log(a):100
            console.log(f):123

    
    (window.foo || (window.foo = 'bar'));
    ==>window.foo = bar
            

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值