V8 是怎么执行加法操作的?
- 把第一个表达式 (AdditiveExpression) 的值赋值给左引用 (lref)。
- 使用 GetValue(lref) 获取左引用 (lref) 的计算结果,并赋值给左值。
- 使用 ReturnIfAbrupt(lval) 如果报错就返回错误。
- 把第二个表达式 (MultiplicativeExpression) 的值赋值给右引用 (rref)。
- 使用 GetValue(rref) 获取右引用 (rref) 的计算结果,并赋值给 rval。
- 使用 ReturnIfAbrupt(rval) 如果报错就返回错误。
- 使用 ToPrimitive(lval) 获取左值 (lval) 的计算结果,并将其赋值给左原生值 (lprim)。
- 使用 ToPrimitive(rval) 获取右值 (rval) 的计算结果,并将其赋值给右原生值 (rprim)。
- 如果 Type(lprim) 和 Type(rprim) 中有一个是 String,则:
- 把 ToString(lprim) 的结果赋给左字符串 (lstr);
- 把 ToString(rprim) 的结果赋给右字符串 (rstr);
- 返回左字符串 (lstr) 和右字符串 (rstr) 拼接的字符串。
- 把 ToNumber(lprim) 的结果赋给左数字 (lnum)。
- 把 ToNumber(rprim) 的结果赋给右数字 (rnum)。
- 返回左数字 (lnum) 和右数字 (rnum) 相加的数值。
通俗地理解,V8 会提供了一个 ToPrimitve 方法,其作用是将 a 和 b 转换为原生数据类型,其转换流程如下:
- 先检测该对象中是否存在 valueOf 方法,如果有并返回了原始类型,那么就使用该值进行强制类型转换;
- 如果 valueOf 没有返回原始类型,那么就使用 toString 方法的返回值;
- 如果 vauleOf 和 toString 两个方法都不返回基本类型值,便会触发一个 TypeError 的错误。

在执行加法操作的时候,V8 会通过 ToPrimitve 方法将对象类型转换为原生类型,最后就是两个原生类型相加,
- 如果其中一个值的类型是字符串时,则另一个值也需要强制转换为字符串,然后做字符串的连接运算。
- 在其他情况时,所有的值都会转换为数字类型值,然后做数字的相加。