让我们看一下这些例子:

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中没有意义。 toStringvalueOf是两个“魔术”方法,通过它们可以将对象转换为原始类型:



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);





在调用@@toPrimitivevalueOf之前先调用toString


  为什么JavaScript会那样表现?


因为这就是规范中定义的方式。如果您想了解其背后的理由,则必须询问做出该决定的人员。

关于javascript - 为什么JavaScript会那样表现?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41007737/

10-14 19:22