前言
最近在写一个 react 项目的时候,不小心在 render 函数运行了 ‘’ + {}, 出现了奇怪的结果 [object Object], 成功的引起了我的注意。
在 JS 规范中加法运算的规则非常简单:你只能加数字和字符串,其他类型会被转成数字或者字符串。为了能清晰明白转化的过程是怎么样的,我们首先要知道几件事。无论何时当段落提到这个(例如 §9.1),这个都是引用 ES 5.1 标准规范来的。
让我们从一个菜鸟开始学习。在 JS 里面值有两种类型:原始值和对象。原始值有:undefined, null, booleans, numbers, and strings。其他都是对象,包括数组和函数。
Converting values 转换值
加法运算符有三种转换类型:他会转换成原始值,数字和字符串
通过 ToPrimitive() 把值转成原始值
ToPrimitive() 有下面的特征:
ToPrimitive(input, PreferredType?)
可选的形参 PreferredType
可以是数字或者字符串。他只表示一个预设值,结果可以是任何原始值。如果 PreferredType
是数字类型,那么转换步骤就是下面这样的:
- 如果输入的是原始值,原地返回输入值
- 否则输入的是对象,调用
obj.valueOf()
。如果结果是原始值就原地返回。 - 否则调用
obj.toString()
。如果结果是原始值就原地返回。 - 否则抛出错误
如果
PreferredType
是字符串。2 和 3 交换。如果PreferredType
没有的话,如果是日期类型它会变成字符串,其他就会变成数字。
通过 ToNumber() 把值转成数字
下面的表格展示了 ToNumber()
是怎么将原始值转成数字类型的
参数 | 结果 |
---|---|
undefined | NaN |
null | +0 |
boolean value | true 变成 1, false 变成 +0 |
number value | – |
string value | 解析字符串变成数字,类似于JS方法里面的Number()。 For example, “324” is converted to 324 |
一个对象通过ToPrimitive(obj, Number) 被转成数字之后调用 ToNumber() 转成原始值
通过 ToString() 把值转成字符串
下面的表格展示了 ToString() 是怎么将原始值转成字符串类型的
参数 | 结果 |
---|---|
undefined | “undefined” |
null | “null” |
boolean value | “true” 或者 “false” |
number value | 直接变成字符串, e.g. “1.765” |
string value | – |
对象通过ToPrimitive(obj,String) 被转成数字之后调用 ToString() 转成原始值
测试下
下面定义的这个对象可以让你观察转换的过程:
var obj = {
valueOf