我在学习 JavaScript 的函数提升( hoisting )时,遇到了三个看似相似但输出不同的例子。根据函数提升的原理,这三个例子的输出应该是相同的,越想越觉得奇怪啊
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
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
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
Yumwey 2023-08-21 21:15:34 +08:00 1
1. 主要是块和全局作用域在 es5 的非严格模式下混淆了,你每一步解析一下提升过程,注意块作用域内 console 输出一直都是 a 的赋值,但是声明式的 Function a 在提升后对全局作用域 a 的引用关系才是 3a 结果, var / 声明式 Function 的提升优先级
2. 加个 'use strict' 就一样了 3. 其实不太需要考虑这个了,直接用 let, const 就好了 |
2
zhouyg 2023-08-21 21:27:05 +08:00 4
建议不学这种糟粕
|
3
klion OP @zhouyg 原因是以前一同学想测试 GPT4 的能力,结果 GPT4 答不上来,我越看也越觉得怪,就上论坛发帖了。stackoverflow 上都说是历史遗留问题,https://stackoverflow.com/questions/58619924/function-declaration-in-block-moving-temporary-value-outside-of-block
|
4
mxT52CRuqR6o5 2023-08-21 21:42:50 +08:00 via Android
不要再研究 sloppy mode 的东西了
我跟你说你这几个 case 在上古浏览器里还有另外不同的表现的 |
5
Rocketer 2023-08-22 00:18:41 +08:00 via iPhone
研究屎山是为了消除它,而不是让自己适配它。
对于已经消除的屎山,还拿他做题玩嘛呢?有公司面试题出这个我都直接怼回去,也没耽误我拿 offer |
6
LUO12826 2023-08-22 01:46:49 +08:00
欢迎使用 Safari ,Safari 里三者输出是一样的。在块作用域内定义用 function 定义函数是 JS 中的标准未定义行为,取决于 JS 引擎的实现
|
7
iOCZ 2023-08-22 09:13:02 +08:00
例子三怎么解释啊?
|
8
stillsilly 2023-08-22 10:16:05 +08:00
吃饱了撑的
|
9
xiangyuecn 2023-08-22 10:27:34 +08:00
你编写的奇怪的代码正在以奇怪的方式运行。
第一行放个 'use strict' 确实能解决不少麻烦。 同一个作用域下不要使用重名的变量,减轻自己的负担。 拒绝使用 const 关键字,我都写 js 了,还 const const const 。 |
10
c3de3f21 2023-08-22 11:10:59 +08:00
@zhouyg 哎,我也是这么认为的,明明有更好的方式来规避这种问题比如 let/const ,可偏偏有公司把这些放到面试题里去。
|
11
zangbianxuegu 2023-08-22 13:42:21 +08:00
@iOCZ 函数声明在全局也创建了同名变量,声明时改变了全局同名变量
|
12
iOCZ 2023-08-22 15:05:56 +08:00
只能这么认为了,就是函数声明提升 var a = function(){},然后紧接着是 window.a = a;然后原来声明之前的 a 赋值,都是 window.a 赋值,函数声明之后的都是 a 赋值。这样能符合所有结果。
|
13
liuidetmks 2023-08-22 18:29:06 +08:00
boring , i +++++i 等于几?
|
14
humbass 2023-08-22 21:31:18 +08:00
es6 给了 let,const ,就是用来解决这些问题体操的。
|
15
Pythoner666666 2023-09-01 11:28:21 +08:00
2023 年了 还在纠结这种问题
|
16
xingguang 2023-09-05 11:41:41 +08:00
我之前看一个视频说 function 的提升有时候很奇怪,规范里都没有定,所以这里是引擎按照自己的理解实现的,所以这样的 function 提升在不同浏览器的结果可能都不一样,所以学习这种提升实在是没必要,面试真遇到了也只能可惜的放弃吧
|