《你不知道的javascript》打卡学习笔记📒(4)

72

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 6 天,点击查看活动详情

提升

变量提升

之前以及了解了有关作用域的相关概念,包括根据声明的位置和方式将变量分配给作用域,函数作用域和块作用域的行为是一样的。可以总结为:任何声明在某个作用域内的变量,都将附属于这个作用域。

我们可能回以为javascript代码是由上到下一行一行执行的。但实际上其实不是这样的:

举例:

第一段代码:

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

会被编译成:

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

第二段代码:

console.log(a); // undefined

var a = 2;

会被编译成:

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

可以看到声明var a;的代码会被提升到代码块的最前面。

并且,只有声明本身会被提升,而赋值或者其他运行逻辑会留在原地。如果提升改变了代码执行的顺序,会造成严重的破坏。

函数提升

foo();

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

被编译成这样:

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

每个作用域会有提升的操作,foo函数自身也会在代码内部对vara进行提升

上面是函数声明,会被提升。但是函数表达式不会被提升。

foo(); // typeError

var foo = function bar() {
    //...
}

函数先于变量提升

前面我们可以看到,函数声明和变量声明都会有一个提升的操作,但是函数的声明会优先于变量的声明。

foo();

var foo;

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

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

最后输出1;

引擎解析代码的时候:

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

var foo;

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

var foo尽管出现在function foo() 的声明之前,但它是重复的声明(因此被忽略了),因为函数声明会被提升到普通变量之前

尽管重复的var声明会被忽略掉,但出现在后面的函数声明还是会覆盖前面的

foo(); // 1 但是3会覆盖 所以最后输出的是3.

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

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

function foo() {
    console.log(3);
}