从 加法运算符 说到 类型转换
从 What is {} + {} in JavaScript? 译文 JavaScript中, {} + {} 等于多少? 说起:
1,先做个简单的测试
1 | [] + [] // "" |
2,javaScript 中的加法运算符
官方文档:(ECMA-262) The Addition operator ( + )
AdditiveExpression : AdditiveExpression + MultiplicativeExpression
前戏:
JavaScript中的值分为原始值( primitives )和对象值( objects )。
原始值包括了 String,Number,Boolean,Null,Undefined。
对象值包括了 Array,Object,Function,RegExp,Date。
转换步骤:
1 | // 1,对 AdditiveExpression 求值,存入 lref。 |
分析 ToPrimitive() 方法:
语法: ToPrimitive(input [, PreferredType])
PreferredType 为可选可以,可以是 Number 或者 String。
1,如果参数为原始值,返回参数本身。
2,如果参数为对象,调用内部方法 DefaultValue(hint)
DefaultValue(hint) 方法中,hint 接收 PreferredType 传入的值,三种情况:
1)hint 为 String:
先调用 toString() 方法,值为原始值则返回该值,
再调用 valueOf() 方法,值为原始值则返回该值,不是,则抛出 TypeError 异常。
2)hint 为 Number:
先调用 valueOf() 方法,值为原始值则返回该值,
再调用 toString() 方法,值为原始值则返回该值,不是,则抛出 TypeError 异常。
3)hint 为空:
如果 input 为 Date 类型,则 hint 为 String,否则 hint 为 Number。
分析 ToNumber() 方法:
ToNumber() 的转换规则
参数类型 | 结果 |
---|---|
Undefined | NaN |
Null | +0 |
Boolean | true 转换为 1。false 转换为 +0. |
Number | 不转换。 |
String | 根据字符串类型的转换规则。(ToNumber Applied to the String Type) |
Object | 先调用 ToPrimitive(input, Number) 转换成原始值,再调用 ToNumber(input)。 |
分析 ToString() 方法:
参数类型 | 结果 |
---|---|
Undefined | “undefined” |
Null | “null” |
Boolean | true 转换为 “true”,false 转换为 “false”。 |
Number | 根据数值类型的转换规则。(ToString Applied to the Number Type) |
String | 不转换。 |
Object | 先调用 ToPrimitive(input, String) 转换成原始值,再调用 ToString(input)。 |
意外:
1 | {} + {} // NaN 或者 "[object Object][object Object]" |
部分浏览器会把 {} 解析为空代码块并忽略掉,所以这里的 + 就变成了一元运算符,
其实就是调用了 ToNumber(GetValue(expr)) 方法。
参考:
运算符:
What is {} + {} in JavaScript?
Fake operator overloading in JavaScript
Improving the JavaScript typeof operator
What is JavaScript’s typeof operator used for?
对象: