我理解这应该是一个块级作用域的问题,代码如下:
var a = 0;
console.log(1, a)
if (true) {
console.log(2, a);
a = 1;
console.log(3, a);
function a() {}
console.log(4, a);
a = 21;
console.log(5, a);
}
console.log(6, a);
输出的结果是
主要是这个 6, 1 我很难理解...
我理解这应该是一个块级作用域的问题,代码如下:
var a = 0;
console.log(1, a)
if (true) {
console.log(2, a);
a = 1;
console.log(3, a);
function a() {}
console.log(4, a);
a = 21;
console.log(5, a);
}
console.log(6, a);
输出的结果是
主要是这个 6, 1 我很难理解...
主要是条件中的函数声明,这个是不确定的行为,最好不要这么搞
https://developer.mozilla.org...
为什么最后是等于1从代码层面很难分析出来,我们通过字节码来一探究竟
StackCheck
LdaZero #常量0
Star r1 #保存至r1 —— global.a
LdaGlobal [0], [0] #window.console
Star r3 #保存至r3
LdaNamedProperty r3, [1], [2] #console.log
Star r2 #保存至r2
LdaSmi [1] #常量1
Star r4 #保存r4
CallProperty2 r2, r3, r4, r1, [4] #window.console.log(r4[=1],r1[=0])
CreateClosure [2], [6], #创建闭包function a
Star r0 #r0=function a
LdaGlobal [0], [0]
Star r3
LdaNamedProperty r3, [1], [7]
Star r2
LdaSmi [2] #常量2
Star r4
CallProperty2 r2, r3, r4, r0, [9] #window.console.log(r4[=2],r0[=fun]])
LdaSmi [1] #常量1
Star r0 #r0=1
LdaGlobal [0], [0]
Star r3
LdaNamedProperty r3, [1], [11]
Star r2
LdaSmi [3] #常量3
Star r4
CallProperty2 r2, r3, r4, r0, [13] #window.console.log(r4[=3],r0[=1])
Mov r0, r1 # r0=>r1, 相当于r1 = r0,即global.a = block.a = 1
LdaGlobal [0], [0]
Star r3
LdaNamedProperty r3, [1], [15]
Star r2
LdaSmi [4] #常量4
Star r4
CallProperty2 r2, r3, r4, r1, [17] #window.console.log(r4[=4],r1[=1])
LdaSmi [21] #常量21
Star r0
LdaGlobal [0], [0]
Star r3
LdaNamedProperty r3, [1], [19]
Star r2
LdaSmi [5] #常量5
Star r4
CallProperty2 r2, r3, r4, r0, [21] #window.console.log(r4[=5],r0[=21])
LdaGlobal [0], [0]
Star r3
LdaNamedProperty r3, [1], [23]
Star r2
LdaSmi [6] #常量6
Star r4
CallProperty2 r2, r3, r4, r1, [25] #window.console.log(r4[=6],r1[=1])
LdaUndefined
Return
这是通过node
编译出的字节码,#
号后面是我标注的注释,重点在于Mov r0,r1
这个指令,也就是在console.log(3, a);
之后,引擎额外执行了这条语句(从代码层面看不出);故而最后再打印r1
的值为1;
如果你开启严格模式,最后输出就会是0,比较符合预期,而严格模式下字节码中并没有Mov
这条指令,而正常模式下Edge的输出则不同于chrome,非严格模式下引擎之间会有自己的优化算法,同一段代码可能输出不一样,尤其像这种不规范的代码
10 回答11.2k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答5.1k 阅读✓ 已解决
3 回答1.9k 阅读✓ 已解决
1 回答3.1k 阅读✓ 已解决
整体的运行流程如下:
至于block.a = 21的时候,global.a还是1, 就不明白是啥机制了, 等大神。