本文主要总结了js里+号操作符是如何隐式转换操作数的
js共有5种原始值:string,number,boolean,null,undefined
二元操作符 a + b
- a && b 是原始值
- a or b 是string, 则另一方转string,之后concate
- a or b 是number, 则另一方转number,之后add(a/b是NaN,则结果为NaN)
- a && b 既不是string,也不是number, 则都转number,之后执行1-2
- a or b 是Object
- 有[Symbol.toPrimitive](hint)方法
- 返回原始值,则执行1
- 否则throw error
- 调用valueOf,如果valueOf返回原始值,则执行1,否则往下判断
- 调用toString(), 如果toString返回原始值,则执行1, 否则throw error
- 说明
- 原生Object非function对象的valueOf方法返回了对象自身,并没有返回原始值,toString返回原始值 "[object object]"
- function对象的valueOf方法返回了对象自身,并没有返回原始值,toString返回原始值 "function(){}"
- 内置对象特例
- Array:由于Array实现了toString但是仅继承了Object的valueOf,所以根据以上规则,Array会先调用valueOf()返回Array非原始值,再调用toString()返回字符串原始值
- Date:如果Object是Date对象的话,则直接执行toString(),即使Date自己实现了valueOf方法返回原始值
- 有[Symbol.toPrimitive](hint)方法
一元操作符 +a
- a 是原始值
- 一律转number
- a 是Object
- 有[Symbol.toPrimitive](hint)方法
- 返回原始值,则执行1
- 否则throw error
- 调用valueOf,如果valueOf返回原始值,则执行1,否则往下判断
- 调用toString(), 如果toString返回原始值,则执行1, 否则throw error
- 有[Symbol.toPrimitive](hint)方法
上面描述了+作为二元和一元操作符的转换规则,但是并没有再进一步讲述原始值转number和string的规则,下面将说明下转换规则
非number原始值转number
- string 转number
- "" 空串转number,值为0
- "12" 数字字符串转number,值为数字
- "12a" 包含非数字字符串转number,值为NaN
- boolean 转number
- true 转number,值为1
- false 转number,值为0
- null 转number,值为0
- undefined 转number,值为NaN
非string原始值转string
- number 转string
- 数字 转string 值为"数字"
- NaN 转string 值为"NaN"
- boolean 转string
- true 转string 值为"true"
- false 转string 值为"fasle"
- null 转string,值为"null"
- undefined 转string,值为"undefined"