Argument Type Result
Undefined “undefined”
Null “null”
Boolean true -> “true”
false – > “false”
Number NaN -> “NaN”
+0 -0 -> “0”
-1 -> “-1”
infinity -> “Infinity”
较大的数科学计数法 (详见规范9.8.1)
String 不转换 直接返回
Object 1. 调用ToPrimitive抽象操作, hint 为 String 将返回值作为 value
2. 返回ToString(value)
String(undefined) // "undefined"
String(null) // "null"
String(true) // "true"
ToPrimitive 抽象操作下面会提及
ToNumber – 规范9.3
按照以下规则转换被传递参数
Argument Type Result
Undefined NaN
Null +0
Boolean true -> 1
false -> +0
Number 直接返回
String 如果不是一个字符串型数字,则返回NaN(具体规则见规范9.3.1)
Object 1. 调用ToPrimitive抽象操作, hint 为 Number 将返回值作为 value
2. 返回ToNumber(value)
ToBoolean – 规范9.2
按照以下规则转换被传递参数
Argument Type Result
Undefined false
Null false
Boolean 直接返回
Number +0 -0 NaN -> false
其他为true
String 空字符串(length为0) -> false
其他为true
Object true
ToPrimitive – 规范9.1
顾名思义,该抽象操作定义了该如何将值转为基础类型(非对象),接受2个参数,第一个必填的要转换的值,第二个为可选的hint,暗示被转换的类型。
按照以下规则转换被传递参数
Argument Type Result
Undefined 直接返回
Null 直接返回
Boolean 直接返回
Number 直接返回
String 直接返回
Object 返回一个对象的默认值。一个对象的默认值是通过调用该对象的内部方法[[DefaultValue]]来获取的,同时传递可选参数hint。
[[DefaultValue]] (hint) – 规范8.12.8
当传递的hint为 String 时候,
如果该对象的toString方法可用则调用toString
如果toString返回了一个原始值(除了object的基础类型)val,则返回val
如果该对象的valueOf方法可用则调用valueOf方法
如果valueOf返回了一个原始值(除了object的基础类型)val,则返回val
抛出TypeError的异常
当传递的hint为 Number 时候,
如果该对象的valueOf方法可用则调用valueOf方法
如果valueOf返回了一个原始值(除了object的基础类型)val,则返回val
如果该对象的toString方法可用则调用toString
如果toString返回了一个原始值(除了object的基础类型)val,则返回val
抛出TypeError的异常
hint的默认值为Number,除了Date object
举个栗子
var a = {}
a.toString = function () {return 1}
a.valueOf = function () {return 2}
String(a) // "1"
Number(a) // 2
a + '' // "2" ???????
+a // 2
a.toString = null
String(a) // "2"
a.valueOf = null
String(a) // Uncaught TypeError: balabala
似乎我们发现了一个很不合规范的返回值,为什么 a + ''不应该返回”1″吗
var a = { b: 42 }
var b = { b: 43 }
a < b // false
a == b // false
a > b // false
a <= b // true
a >= b // true
是不是感觉到世界又崩塌了???
让我们来仔细分析一下
var a = { b: 42 }
var b = { b: 43 }
a < b // false
// 1. 两遍调用ToPrimitive, 返回[object Object] 两遍一致 返回 false
a == b // false
// 两遍不同的引用,返回false
a > b // false
// 同 a < b
a <= b // true
// 按规范其实是处理成 !(a > b) 所以为true
a >= b // true
所以在不相等比较的时候,我们最后还是进行手动的类型转换较为安全