这里为什么输出100,而不是str
var o1 = {
toString: function(){
return "str";
},
valueOf: function(){
return 100;
}
};
console.log("" + o1);//返回100
这里为什么输出100,而不是str
var o1 = {
toString: function(){
return "str";
},
valueOf: function(){
return 100;
}
};
console.log("" + o1);//返回100
+操作符在执行操作时,从左往右遵循以下规则
1)如果2个操作都是数字,直接相加
2)如果2个操作数都是字符串,直接执行字符串连接
3)如果一个操作是对象的话,日期对象直接调用toString方法;其它对象检查其是否有valueOf方法,如果没有调用toString方法;valueOf方法如果返回的是一个原始值(数字,字符串,null,undefine,NaN),那么就返回这个原始值,如果不是原始值,那么再调用toString方法返回
4)完成对象的转换后,如果下一个操作数为字符串话,那么原始值执行到字符串的转话,2者相加;如果另一个操作数为数字的话,那么原始值转为数字后,再执行数字相加操作
也就是对于+操作符来说,要么2个操作数为字符串,要么全部为数字
console.log(true+123);//124
console.log(true+'123');//true123
console.log(NaN+'123');;//NaN123
console.log(NaN+123);//NaN
console.log(new String('1')+123);//1123
console.log(new Number(12)+123);//135
console.log(undefined+'123');//undefined123
console.log(undefined+123);//NaN 转成数字为NaN
console.log(null+'123');//null123
console.log(null+123);//123 null转成数字为0
var o1 = {
toString: function(){
return "str";
},
valueOf: function(){
return {};
}
};
console.log(o1+'');//str
o1 = {
toString: function(){
return "str";
},
valueOf: function(){
return 'valueOf';
}
};
console.log(o1+'');//valueOf
o1 = {
toString: function(){
return "str";
},
valueOf: function(){
return undefined;
}
};
console.log(o1+'');//undefined
根据ES5标准 http://es5.github.io/#x11.6.1,会对左右操作数分别执行ToPrimitive
Let lprim be ToPrimitive(lval).
Let rprim be ToPrimitive(rval).
,对于对象执行ToPrimitive,其实就是调用内部的[[DefaultValue]]方法,这个方法可能为valueOf,也可能为toString,在这种情况下是valueOf,因为:
When the [[DefaultValue]] internal method of O is called with no hint, then it behaves as if the hint were Number
但是有一个例外就是Date对象:
unless O is a Date object (see 15.9.6), in which case it behaves as if the hint were String.
即:
"" + new Date //Mon Jan 18 2016 17:27:54 GMT+0800 (中国标准时间) 调用的是内部的toString
js中对象到字符串的转换经过了如下这些步骤:
如果对象具有toString()方法,则调用该方法。如果它返回一个原始值,JavaScript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
如果对象没有toString()方法,或者这个方法并不返回一个原始值,那么JavaScript会调用valueOf()方法。如果存在这个方法,则JavaScript调用它。如果返回值是原始值,JavaScript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
否则JavaScript无法从toString()或valueOf()获得原始值,因此这时他讲跑出一个类型错误异常。
在对象到数字的转换过程中,JavaScript做了同样的事情,只是它会首先尝试调用valueOf()方法。
JavaScript的“+”运算符可以进行数学假发和字符串连接操作。如果它的其中一个操作数是对象,则JavaScript将使用特殊的方法将对象转换为原始值,而不是使用其他算术运算符的方法执行对象到数字的转换。“==”与此类似。
对于所有非日期的对象来说,对象到原始值的转换基本上是对象到数字的转换(首先调用valueOf()),日期对象则使用对象到字符串的转换模式。
10 回答11.1k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答5.1k 阅读✓ 已解决
3 回答1.9k 阅读✓ 已解决
使用运算符操作对象的时候,调用的是 valueOf 方法, 要调用 toString 方法,直接
console.log(o1);
即可。这里有份实际调用的表
当然,这是在同时定义了 valueOf 和 toString 的情况下出现的