本帖最后由 hans7 于 2023-6-16 00:55 编辑
想实现这个例子的目标只需要把dict.node改成dict[node],dict.node相当于dict['node']。
打开 https://astexplorer.net/ 查看 这条语句 dict.node === dict[node] 的Babel AST
两者区别只有一个:computed是true和false。但含义是不一样的。
接下来看下computed是true和false时v8生成的字节码的区别。准备一段代码 computed_demo.js
let dict = {
node: 'node'
};
let node = '_node';
console.log(dict.node === dict[node]);
命令:./d8 computed_demo.js --print-bytecode
获取字节码。如果没有d8.exe也可以用nodejs代替,node --print-bytecode computed_demo.js。简单分析如下。结论很简单:dict.node用了LdaNamedProperty指令,dict[node]用了LdaKeyedProperty指令。这就是两者的不同。Lda类指令是将结果放到累加寄存器的。
[generated bytecode for function: (0x00650824fa59 <SharedFunctionInfo>)]
Parameter count 1
Register count 5
Frame size 40
000000650824FADA @ 0 : 7d 00 00 29 CreateObjectLiteral [0], [0], #41 ; 定义 dict
000000650824FADE @ 4 : 1d 02 StaCurrentContextSlot [2] ; 简单理解为放到 globalThis 地址2处
000000650824FAE0 @ 6 : 12 01 LdaConstant [1] ; 常量池[1]处为字符串 '_node'
000000650824FAE2 @ 8 : 1d 03 StaCurrentContextSlot [3]
000000650824FAE4 @ 10 : 13 02 01 LdaGlobal [2], [1] ; 取常量池2处的值,即'console',放到累加寄存器。后面的 [1] 是反馈向量,本例不用管。
000000650824FAE7 @ 13 : 26 f9 Star r2 ; 累加寄存器当前值存入r2寄存器,即r2 = 'console'
000000650824FAE9 @ 15 : 28 f9 03 03 LdaNamedProperty r2, [3], [3] ; console取log属性
000000650824FAED @ 19 : 26 fa Star r1 ; console.log对象的地址放到r1寄存器
000000650824FAEF @ 21 : 1a 02 LdaCurrentContextSlot [2] ; globalThis [2]对应dict,加载到累加寄存器
000000650824FAF1 @ 23 : 26 f8 Star r3 ; r3现在指向dict对象
000000650824FAF3 @ 25 : 28 f8 04 05 LdaNamedProperty r3, [4], [5] ; 常量池[4]对应'node',dict取'node'属性
000000650824FAF7 @ 29 : 26 f8 Star r3 ; dict['node']结果放到r3寄存器
000000650824FAF9 @ 31 : 1a 02 LdaCurrentContextSlot [2]
000000650824FAFB @ 33 : 26 f7 Star r4 ; r4指向dict对象
000000650824FAFD @ 35 : 1a 03 LdaCurrentContextSlot [3] ; globalThis [3]对应'_node',至累加寄存器
000000650824FAFF @ 37 : 2a f7 07 LdaKeyedProperty r4, [7] ; 取dict[node],即dict['_node'],结果放在累加寄存器
000000650824FB02 @ 40 : 68 f8 09 TestEqualStrict r3, [9] ; 累加寄存器当前值与r3的值比较,结果放到累加寄存器
000000650824FB05 @ 43 : 26 f8 Star r3 ; dict.node === dict[node]结果放到r3
000000650824FB07 @ 45 : 59 fa f9 f8 0a CallProperty1 r1, r2, r3, [10] ; 调用console.log
000000650824FB0C @ 50 : 26 fb Star r0
000000650824FB0E @ 52 : aa Return
Constant pool (size = 5)
000000650824FA9D: [FixedArray] in OldSpace
- map: 0x0065080404b1 <Map>
- length: 5
0: 0x00650824fa81 <ObjectBoilerplateDescription[3]>
1: 0x00650824fa11 <String[#5]: _node>
2: 0x0065081c6971 <String[#7]: console>
3: 0x0065081c69e5 <String[#3]: log>
4: 0x00650824fa01 <String[#4]: node>
Handler Table (size = 0)
Source Position Table (size = 0)
false
|