Skip to main content

07 类型转换:V8 如何实现1+_2_

什么是类型系统 (Type System)

对机器语言来说,数据都是一堆二进制代码,CPU 处理数据时,并没有类型的概念,CPU 所做的仅仅是移动数据,比如对其进行移位,相加或相乘。

在高级语言中,会为操作的数据赋予指定的类型,类型可以确认一个值或者一组值具有特定的意义和目的。在某些更高级的语言中,还可以根据数据推断出类型。

var counter = 100 # 赋值整型变量
let miles = 1000.0 # 浮点型
const name = "John" # 字符串

引入了类型之后,编译器或者解释器就可以根据类型来限制一些有害的或者没有意义的操作。

每种语言都定义了自己的类型,还定义了如何操作这些类型,另外还定义了这些类型应该如何相互作用,称为类型系统。

V8 是怎么执行加法操作的

V8 会严格根据 ECMAScript 规范来执行操作。ECMAScript 是一个语言标准,JavaScript 就是 ECMAScript 的一个实现。ECMAScript 定义怎么执行加法操作:

AdditiveExpression : AdditiveExpression + MultiplicativeExpression


V8 提供了一个 ToPrimitive 方法,将 a 和 b 转换为原生数据类型:

  • 先检测该对象中是否存在 valueOf 方法,如果有并返回了原始类型,就使用该值进行强制类型转换;
  • 如果 valueOf 没有返回原始类型,那么就使用 toString 方法的返回值;
  • 如果 vauleOf 和 toString 两个方法都不返回基本类型值,便会触发一个 TypeError 的错误。

Number(1).toString() + "2"

var Obj = {
toString() {
return "200";
},
valueOf() {
return 100;
},
};
Obj + 3;

// result
103;
var Obj = {
toString() {
return new Object()
},
valueOf() {
return new Object()
}
}
Obj+3

// result

VM263:9 Uncaught TypeError: Cannot convert object to primitive value
at <anonymous>:9:6