让我们看一下这些例子:
var a = 1;
var b = { toString:function() {return '1'} };
var c = 1;
a + b + c === "111" // true
这真是令人震惊。我知道当我们使用+运算符时,JS解释器会执行ToPrimitive或ToString操作。但是,当没有提示PreferredType时,为什么将对象b转换为字符串。因此,它可能正在使用ToString操作。
另请注意:如果对象上存在toString方法,则仅将其转换为字符串,为什么?如果我将该方法称为“ toNumber”,为什么不将其转换为数字?
为什么JavaScript会那样表现?
最佳答案
但是,当没有提示PreferredType时,为什么将对象b转换为字符串。
如果未传递任何提示,则将首先调用对象的valueOf
方法。但是由于b.valueOf()
不会返回原始值(默认情况下会返回对象本身),因此下一步将调用b.toString()
。
请参见specification。
转换规则可以总结如下:
如果没有任何提示或提示为number
,请首先调用valueOf
。
如果提示是string
,请首先调用toString
。
如果返回值不是原始值,则调用另一个方法。
如果返回值仍然不是原始值,则抛出错误。
它仅在对象上存在toString方法时才转换为字符串,为什么?
不确定我是否理解此声明。每个对象都有一个toString
方法。如果尝试对没有toString
方法的对象(通过Object.create(null)
)执行此操作,则会引发错误。
如果我将该方法称为“ toNumber”,为什么不将其转换为数字?
因为toNumber
在JavaScript中没有意义。 toString
和valueOf
是两个“魔术”方法,通过它们可以将对象转换为原始类型:
var n = 1;
var o = {
toString() { return 'bar'; },
valueOf() { return 2; }
};
console.log(n + o);
console.log(String(o));
如果这些方法均未返回原语,则也会产生错误。
var n = 1;
var o = {
toString() { return this; },
};
console.log(n + o);
这两种方法及其命名似乎有些武断。从ES6开始,定义转换函数的首选方法是使用众所周知的
@@toPrimitive
符号:var a = 1;
var b = { [Symbol.toPrimitive]: function() {return 1} };
var c = 1;
console.log(a + b + c);
在调用
@@toPrimitive
或valueOf
之前先调用toString
。为什么JavaScript会那样表现?
因为这就是规范中定义的方式。如果您想了解其背后的理由,则必须询问做出该决定的人员。
关于javascript - 为什么JavaScript会那样表现?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41007737/