三个 JavaScript 例子中的函数提升为何导致不同的输出?

264 天前
 klion

问题描述

我在学习 JavaScript 的函数提升( hoisting )时,遇到了三个看似相似但输出不同的例子。根据函数提升的原理,这三个例子的输出应该是相同的,越想越觉得奇怪啊

例子 1

var a = 0;
console.log("1 a:", a);
if(true){
    a = 1;
    function a() {}
    a = 5;
    console.log("2 a:", a);
}
console.log("3 a:", a);

经过验证,输出结果为:

1 a: 0
2 a: 5
3 a: 1

例子 2

var a = 0;
console.log("1 a:", a);
if(true){
    a = 1;
    a = 5;
    console.log("2 a:", a);
    function a() {}
}
console.log("3 a:", a);

经过验证,输出结果为:

1 a: 0
2 a: 5
3 a: 5

例子 3

var a = 0;
console.log("1 a:", a);
if(true){
    function a() {}
    a = 1;
    a = 5;
    console.log("2 a:", a);
}
console.log("3 a:", a);

经过验证,输出结果为:

1 a: 0
2 a: 5
3 a: f a() {}

问题

  1. 这几个例子在函数提升方面有何不同?
  2. 为什么每个例子的输出都不相同?
1812 次点击
所在节点    Node.js
16 条回复
Yumwey
264 天前
1. 主要是块和全局作用域在 es5 的非严格模式下混淆了,你每一步解析一下提升过程,注意块作用域内 console 输出一直都是 a 的赋值,但是声明式的 Function a 在提升后对全局作用域 a 的引用关系才是 3a 结果, var / 声明式 Function 的提升优先级
2. 加个 'use strict' 就一样了
3. 其实不太需要考虑这个了,直接用 let, const 就好了
zhouyg
264 天前
建议不学这种糟粕
klion
264 天前
@zhouyg 原因是以前一同学想测试 GPT4 的能力,结果 GPT4 答不上来,我越看也越觉得怪,就上论坛发帖了。stackoverflow 上都说是历史遗留问题,https://stackoverflow.com/questions/58619924/function-declaration-in-block-moving-temporary-value-outside-of-block
mxT52CRuqR6o5
264 天前
不要再研究 sloppy mode 的东西了
我跟你说你这几个 case 在上古浏览器里还有另外不同的表现的
Rocketer
264 天前
研究屎山是为了消除它,而不是让自己适配它。

对于已经消除的屎山,还拿他做题玩嘛呢?有公司面试题出这个我都直接怼回去,也没耽误我拿 offer
LUO12826
263 天前
欢迎使用 Safari ,Safari 里三者输出是一样的。在块作用域内定义用 function 定义函数是 JS 中的标准未定义行为,取决于 JS 引擎的实现
iOCZ
263 天前
例子三怎么解释啊?
stillsilly
263 天前
吃饱了撑的
xiangyuecn
263 天前
你编写的奇怪的代码正在以奇怪的方式运行。

第一行放个 'use strict' 确实能解决不少麻烦。

同一个作用域下不要使用重名的变量,减轻自己的负担。

拒绝使用 const 关键字,我都写 js 了,还 const const const 。
c3de3f21
263 天前
@zhouyg 哎,我也是这么认为的,明明有更好的方式来规避这种问题比如 let/const ,可偏偏有公司把这些放到面试题里去。
zangbianxuegu
263 天前
@iOCZ 函数声明在全局也创建了同名变量,声明时改变了全局同名变量
iOCZ
263 天前
只能这么认为了,就是函数声明提升 var a = function(){},然后紧接着是 window.a = a;然后原来声明之前的 a 赋值,都是 window.a 赋值,函数声明之后的都是 a 赋值。这样能符合所有结果。
liuidetmks
263 天前
boring , i +++++i 等于几?
humbass
263 天前
es6 给了 let,const ,就是用来解决这些问题体操的。
Pythoner666666
253 天前
2023 年了 还在纠结这种问题
xingguang
249 天前
我之前看一个视频说 function 的提升有时候很奇怪,规范里都没有定,所以这里是引擎按照自己的理解实现的,所以这样的 function 提升在不同浏览器的结果可能都不一样,所以学习这种提升实在是没必要,面试真遇到了也只能可惜的放弃吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/967183

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX