JavaScript声明提升

声明提升就好像把声明(变量声明和函数声明)从它们所在代码中出现的位置移到了最上面。直觉上我们会以为JavaScript代码是由上到下一行一行执行的,但实际上这并不完全正确,还要考虑声明提升的存在。

1. 考虑下面关于变量声明提升的代码:

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

按照由上到下一行一行执行的思路:var a 声明在 a = 2 之后,所以a被重新赋值了,最后会输出undefined?

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

按照由上到下一行一行执行的思路:变量a在使用前没有先声明,所以会抛出ReferenceError异常?

代码执行一下的话,我们会发现答案是2 和 undefined,所以上面的思路是行不通的。正确的思路是:包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理,就好像变量和函数声明会从它们所在代码中出现的位置被“移动”到了最上面,这个过程也就是提升。

我们习惯把var a = 2; 看做一个声明,而实际上JavaScript引擎并不这么认为。它将 var a 和 a = 2 当做两个单独的声明, 第一个是编译阶段的任务,而第二个则是执行阶段的任务。只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。

按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:

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

这样的话,再按照由上到下一行一行执行的思路,答案很明显就是2 和 undefined了。

2. 考虑下面关于函数声明提升的代码:

fn();
function fn(){
    console.log(a); // ??
    var a = 2;
}

按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:

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

这样的话,再按照由上到下一行一行执行的思路,答案就是undefined了。


注:函数声明会被提升,但是函数表达式却不会被提升。

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

// Uncaught TypeError: fn is not a function

函数声明和变量声明都会被提升,但是函数会首先提升,然后才是变量。即函数声明的优先级要大于变量声明。

3. 考虑下面关于声明提升优先级的代码:

var foo;

foo();   // ??

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

按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:

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

var foo;    // 重复声明,被忽略

foo();    // 1

尽管var foo出现在function foo之前,但是函数提升的优先级要大于变量提升,所以 function foo(){} 会在var foo之前;但是var foo是重复声明所以被忽略了,所以最终输出1。


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

var foo;

foo();    // 3

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

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

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

4. 考察声明提升的例子

alert(a);       // ??
a();            // ??
var a = 3;
function a(){
    alert(10)
}
alert(a)        // ??
a = 6;
a();            // ??

答案:

alert(a);       // function a(){ alert(10) } 
a();            // 10
var a = 3;
function a(){
    alert(10)
}
alert(a)        // 3
a = 6;
a();            // Uncaught TypeError: a is not a function


参考阅读

  1. 你不知道的JavaScript上卷>第4章提升
  2. JavaScript系列文章:变量提升和函数提升
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在 JavaScript 中,变量提升指的是在代码执行前,变量声明就已经被提升(即复制)到了当前作用域的最顶端。这意味着,无论变量在代码中定义在哪里,它都会在代码执行前被提升到所在作用域的最顶端。 例如: ``` console.log(a); // undefined var a = 1; ``` 在这个例子中,虽然变量 `a` 实际上定义在了第二行,但是在代码执行前,它已经被提升到了最顶端。所以在第一行中,当我们尝试访问 `a` 时,它已经被声明过了,所以输出 `undefined`。 注意,变量提升仅仅是声明(复制)被提升,而不是赋值。所以在上面的例子中,变量 `a` 的值在第二行被赋值为 1,而不是在第一行被赋值为 `undefined`。 ### 回答2: JavaScript变量提升JavaScript中的一种特性。在JavaScript中,变量的声明会在代码执行之前进行处理,也就是说它们会被“提升”到其作用域的顶部。这意味着你可以在声明之前使用变量,而不会引发错误。 例如,假设我们有以下的JavaScript代码: ``` console.log(x); // undefined var x = 5; console.log(x); // 5 ``` 在这个例子中,变量x被提升到了代码的顶部,所以在第一个console.log语句中,x被声明了但尚未被赋值,所以它的值是undefined。然后,变量x被赋值为5,并在第二个console.log语句中打印出来。 需要注意的是,只有变量的声明会被提升,而不是它们的赋值。例如: ``` console.log(y); // ReferenceError: y is not defined y = 10; console.log(y); // 10 var y; ``` 在这个例子中,变量y在它的声明之前被使用会引发错误。只有在变量y的声明后,它的赋值才会生效。 变量提升在理解JavaScript的作用域和执行顺序时非常重要。它使得我们可以在变量声明之前使用变量,但也可能导致一些意外的结果,所以在编写代码时要小心使用。 ### 回答3: JavaScript变量提升是指在代码执行之前,所有变量的声明都会被提升到代码的顶部。这意味着我们可以在变量声明之前使用这些变量。但是要记住的是,只有变量的声明会被提升,而不是初始化。 例如,我们可以在变量声明之前输出变量的值: console.log(x); // undefined var x = 5; 这段代码中,变量x在声明之前被赋值为undefined,因此在打印x时,它的值是undefined。 变量提升还可以应用于函数声明。我们可以在函数声明之前调用函数: myFunction(); // "Hello, World!" function myFunction() { console.log("Hello, World!"); } 在这个例子中,函数myFunction在声明之前被调用,所以我们可以在调用函数之前定义它。 需要注意的是,变量提升仅适用于使用var关键字声明的变量,而不适用于使用let和const关键字声明的变量。使用let和const声明的变量是块级作用域的,不会被提升。 综上所述,JavaScript变量提升是一种将变量的声明提升到代码顶部的机制,使我们可以在变量声明之前使用这些变量。这在代码书写和阅读上提供了一定的便利,但也需要注意一些细节,以避免出现意料之外的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值