JS--提升

一、什么是提升

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

上面的代码输出的是否是undefined?

答案是否定的,执行完毕我们会发现打印出a的值为2,这个似乎和代码自上而下执行的结果相违背,代码执行的过程中到底发生了什么?

要明白发生了什么首先要解释下js程序的执行过程:
js通常被认为是动态语言或解释语言,但是事实上它是一门编译语言,只不过它不是像java等提前编译,而是在执行代码前的几微秒瞬间编译。

编译的过程和传统编译编译语言非常相似:


js简单编译过程示意图.png

编译阶段的一部分工作就是找到所有的变量声明并将它们绑定在对应的作用域中(函数作用域或块作用域)。

因此,正确的思考思路是,包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。所以上面代码的正确执行过程是:

var a;
a = 2;
console.log(a);
以上这种声明提前的现象就是提升。

二、提升示例

1. 函数声明会提升,函数表达式不会提升
foo();
bar();

var foo = function bar() {
}

上述代码声明提升后如下:

var foo;
foo()//TypeError: foo is not a function
bar()//ReferenceError: bar is not defined

foo = function () {
    var bar = self
}

只有声明会提升,表达式不会提升,所以foo声明被提前,此时foo为undefined,进行函数调用会发生TypeError错误,bar不会提升,此时会报错ReferenceError。

2. 函数和变量都会提升,函数提升会在变量提升之前
foo();
var foo;
function foo() {
    console.log(1)
}

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

输出的结果是1,进行函数提升后:

function foo() {
    console.log(1)
}

foo();

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

由此也说明定义相同名称的变量是一件很糟糕的事情。

总结:

  1. 只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。如果提升改变了代码执行的顺序,会造成非常严重的破坏。
  2. 函数声明会被提升,但是函数表达式却不会被提升。
  3. 函数声明和变量声明都会提升,但是函数声明会提升到变量声明之前。要避免重复声明。

参考文档:《你不知道的JavaScript(上卷)》

你可能感兴趣的:(JS--提升)