预编译

132 阅读1分钟

也叫预解析,

进入作用域后 代码执行前,

用var声明的变量 声明提前 赋值不动

函数声明 声明提前 赋值提前

使得变量和函数在声明前就使用不会报错

<script>
var a = 1;
console.log(a);
function test(a) {
  console.log(a);
  var a = 123;
  console.log(a);
  function a() {}
  console.log(a);
  var b = function() {}
  console.log(b);
  function d() {}
}
var c = function (){
console.log("I at C function");
}
console.log(c);
test(2);
</script>
情况1:进入全局作用域

1.变量声明 变量名作为全局对象属性 值为undefined

2.函数声明 函数名作为全局对象属性 值为函数体

3.如果同名,函数声明覆盖变量声明

//抽象描述
    GO/window = {
        a: undefined,
        test: function(a) {
            console.log(a);
            var a = 123;
            console.log(a);
            function a() {}
            console.log(a);
            var b = function() {}
            console.log(b);
            function d() {}
        },
        c: undefined,
    }
情况2:进入函数作用域
  1. 创建AO活动对象(Active Object);
  2. 形参和变量声明 变量名作为AO的属性,值是undefined;
  3. 实参赋值给形参;
  4. 函数声明 函数名作为AO的属性,值是函数体;
  5. 如果同名,函数声明覆盖变量声明
//抽象描述
    AO = {
        a:function a() {},
        b:undefined
        d:function d() {}
    }
情况3:进入块级作用域(es6)

相当于用var声明的函数表达式

// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function
// 相当于如下代码
function f() { console.log('I am outside!'); }
(function () {
  var f = undefined;
  if (false) {
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function
注意

1.变量前没有var ,则这个变量是全局变量

2.用let或const声明的变量,没有预编译(即变量提升)