我又跌跌撞撞地回到了旧的'12' + 2 = '122'
我想深入了解这里发生的事情,所以我的第一个论文是
也许Javascript将正确的操作数转换为第一个操作数的类型,然后 然后运行,就像这样:
'12' + String(2) = '122'
一切顺利...
但不是,因为12 + '2' = '122'
也是如此;因此,引擎的魔力显然是在吸引人而不是转换成数字。
然后我的第二个论文是
也许引擎会枚举所有操作数并寻找类似于C#的“运算符替代”?然后喜欢执行该命令而不是执行自已的魔术操作?
当我意识到'5' * '8' = 40
也将两个操作数都转换为Number并执行操作时,我的困惑变得更加奇怪。
我可能真正理解的唯一方法是直接从GitHub读取V8代码
我能找到的更远的地方是v8/src/parsing/parser-base.h
第2865行
// We have a "normal" binary operation.
x = factory()->NewBinaryOperation(op, x, y, pos);
if (op == Token::OR || op == Token::AND) {
impl()->RecordBinaryOperationSourceRange(x, right_range);
}
从这里我迷路了,因为我找不到这个factory()
的来源。
长话短说,V8引擎源代码中的JavaScript“魔术”类型从何而来?
答案 0 :(得分:2)
V8开发人员在这里。
在V8中,有几种用于各种加法和其他操作情况的快速路径。如果您想研究规范(缓慢但完整)的版本,可以寻找Object::Add in src/objects.cc.
也就是说,这里的真理不是任何给定引擎的实现,而是JavaScript规范。 +
操作符应该在此处定义:https://tc39.github.io/ecma262/#sec-addition-operator-plus。
任何引擎的实现要么精确地做到这一点,要么与外界的东西都无法区分-否则就是一个错误。 Object::Add
的实现读取的内容几乎与规范完全相同;-)