typeof (new Date()) + 1 // 结果为啥是"string"
typeof (new Date()) - 1 //"number"
console.log((new Date()) + 1); //"Mon Feb 22 2016 14:13:27 GMT+0800 (中国标准时间)1"
console.log((new Date()) - 1); //1456121787203
({valueOf:function(){return 3;},toString:function(){return 2;}}) + 1 //4
({valueOf:function(){return {};},toString:function(){return 5;}}) + 1 //6
console.log((new Date()) + 1);
这行js代码,不是应该先调用 Date的valueOf()
,如果valueOf()
不返回简单类型,再调用Date的toString()
的吗?
可事实上确实直接调用了toString()
方法
+
有两种含义,一个是字符串连接,一个是加法。所以js加法有点儿复杂。首先吧两边的数转换成基本类型,而转换成基本类型的时候默认先调用
valueof
,然后是toString
,除了new Date
类型之外。所以对于new Date 优先调用的是toString 。而
+
操作,如果其中一个是字符串的话,那么就认为是字符串链接。没有字符串才认为是数字的加法。-
,就只有数字减法的意思,所以类型转换都是ToNumber
也就是说优先调用valuleOf
。下面的不想看就算了,跟上面一个意思。
ECMAscript 标准摘录(修改过):
对加法的描述:
Let lprim be ToPrimitive(lval).
Let rprim be ToPrimitive(rval).
If Type(lprim) is String or Type(rprim) is String, then
Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim).
减法:
Let lnum be ToNumber(lval).
Let rnum be ToNumber(rval).
Return the result of applying the subtraction operation to lnum and rnum.
ToNumber定义: ToPrimitive(input argument, hint Number)
ToPrimitive定义:
When the ToPrimitive internal method of O is called with no hint, then it behaves as if the hint were
Number, unless O is a Date object。
ToPrimitive(with hint String) :
1、 If IsCallable(toString) is true then,
----a . Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.
----b . If str is a primitive value, return str.
2、If IsCallable(valueOf) is true then,
----a. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.
----b. If val is a primitive value, return val.
3、 Throw a TypeError exception
ToPrimitive(with hint Number) :
1、If IsCallable(valueOf) is true then,
----a. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.
----b. If val is a primitive value, return val.
2、 If IsCallable(toString) is true then,
----a . Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.
----b . If str is a primitive value, return str.
3、 Throw a TypeError exception