JavaScript之变量提升

提升

提升现象的出现,是因为代码在运行前,引擎会先进行编译。这个过程就好像变量和函数声明从它们在代码中出现的位置被“移动”到了最上面。

准则

  1. 只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。
  2. 每个作用域都会进行提升操作。
  3. 函数声明会被提升,但是函数表达式却不会被提升。
  4. 函数声明和变量声明都会被提升,是函数会首先被提升,然后才是变量。
  5. let和const进行的声明不会在块作用域中进行提升。

例子

示例1

console.log(a);
var a = 2;

编译后的结果是:

var a;
console.log(a); // undefined
a = 2;

示例2

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

编译后的结果是:

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

原理参见第2条。

示例3

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

编译后的结果是:

var foo;
foo(); // 不是ReferenceError,而是TypeError
foo = function() {
    console.log(2);
};

原理参见第三条。

示例4

foo();
var foo;
function foo() {
    console.log(1);
}
foo = function() {
    console.log(2);
}

编译后的结果是:

function foo() {
    console.log(1);
}
foo(); // 1
foo = function() {
    console.log(2);
}

原理见第4条,函数被提升,然后重复声明的变量忽略。但如果重复声明的是函数,则发生覆盖操作,如下:

foo(); // 3
function foo() {
    console.log(1);
}
var foo = function() {
    console.log(2);
};
function foo() {
    console.log(3);
}

编译后的结果是:

function foo() {
    console.log(3);
}
foo(); // 3
foo = function() {
    console.log(2);
};

你可能感兴趣的:(前端基础)