《你不知道的JavaScript(上卷)》 4.12 第四章提升

本文深入探讨了JavaScript中的提升现象,解释了变量和函数声明如何在执行前被处理,导致代码行为可能与预期不符。在编译阶段,声明会被提升到作用域顶部,而赋值和其他逻辑保持原位。函数声明优先于变量声明,并且重复的声明可能导致意外行为。了解这些原理对于避免潜在问题至关重要。
摘要由CSDN通过智能技术生成

《你不知道的JavaScript(上卷)》

4.1先有鸡还是先有蛋

直觉上会认为 JavaScript 代码在执行时是由上到下一行一行执行的。 但实际上这并不完全
正确, 有一种特殊情况会导致这个假设是错误的。

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

你认为 console.log(…) 声明会输出什么呢?

很多开发者会认为是 undefined, 因为 var a 声明在 a = 2 之后, 他们自然而然地认为变量
被重新赋值了, 因此会被赋予默认值 undefined。 但是, 真正的输出结果是 2。

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

你可能会认为这个代码片段也会有同样的行为而输出 2。 还有人可能会认为由于变量 a 在使用前没有先进行声明,因此会抛出 ReferenceError 异常。
不幸的是两种猜测都是不对的。 输出来的会是 undefined。

4.2编译器

回忆一下, 引擎会在解释 JavaScript 代码之前首先对其进行编译。 编译阶段中的一部分工作就是找到所有的声明, 并用合适的作用域将它们关联起来。

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

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

上述第一个代码段在编译器眼里是这样的

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

第二个:

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

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

换句话说, 先有蛋(声明) 后有鸡(赋值) 。 只有声明本身会被提升, 而赋值或其他运行逻辑会留在原地。 如果提升改变了代码执行的顺序, 会造成非常严重的破坏。

4.3函数优先

函数声明和变量声明都会被提升。 但是一个值得注意的细节(这个细节可以出现在有多个
“重复” 声明的代码中) 是函数会首先被提升, 然后才是变量

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

会输出1而不是2,这个代码片段会被引擎理解为如下形式:

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

注意:

var foo 尽管出现在 function foo()… 的声明之前, 但它是重复的声明(因此被忽
略了), 因为函数声明会被提升到普通变量之前。
尽管重复的 var 声明会被忽略掉, 但出现在后面的函数声明还是可以覆盖前面的!

4.4小结

我们习惯将 var a = 2; 看作一个声明, 而实际上 JavaScript 引擎并不这么认为。 它将 var a
和 a = 2 当作两个单独的声明, 第一个是编译阶段的任务, 而第二个则是执行阶段的任务。
这意味着无论作用域中的声明出现在什么地方, 都将在代码本身被执行前首先进行处理。
可以将这个过程形象地想象成所有的声明(变量和函数) 都会被“移动” 到各自作用域的
最顶端, 这个过程被称为提升

声明本身会被提升, 而包括函数表达式的赋值在内的赋值操作并不会提升。
要注意避免重复声明, 特别是当普通的 var 声明和函数声明混合在一起的时候, 否则会引起很多危险的问题!

Page 36 ~ Page 42 2021.04.12

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值