变量提升 - 你不知道的 JS

先有鸡还是先有蛋(现有声明再有赋值)

console.log( a );  // undefined
var a = 2;
  1. 引擎会在解释 JavaScript 代码之前首先对其进行编译。
  2. 编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。
  3. 正确的思考思路是,包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。

当你看到 var a = 2; 时,可能会认为这是一个声明。但 JavaScript 实际上会将其看成两个
声明:var a;a = 2;
第一个定义声明是在编译阶段进行的。
第二个赋值声明会被留在原地等待执行阶段。

上面的代码片段会以如下形式进行处理

// 编译阶段
var a;
// 执行阶段
console.log(a);
a = 2;

这个过程就好像变量和函数声明从它们在代码中出现的位置被 “移动”
到了最上面。这个过程就叫作 ** 提升 **。

对于函数,函数声明被提升的救过就是,可以在声明前执行。

foo();
function foo() {
    console.log( a ); // undefined
    var a = 2;
}

每个作用域都会进行提升操作

对于函数表达式,不会存在提升。

foo(); // 不是 ReferenceError, 而是 TypeError!
bar(); // ReferenceError
wahtthefuck() // ReferenceError
var foo = function bar() {
    // ...
};

变量的提升会导致报 ReferenceError,但是这里是 TypeError。
foo() 由于对 undefined 值进行函数调用而导致非法操作,因此抛出 TypeError 异常。
至于 bar(),外部作用域完全没有声明这个变量,所以报 ReferenceError


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论。
我的空间