为什么在字符串连接操作中没有调用Number.toString()?

时间:2018-03-25 17:51:22

标签: javascript string prototype

在尝试Object.toString()函数的默认行为时,我注意到下面的字符串连接可预测地在目标对象上调用toString()

var x = { toString: () => "one" };
var y = { toString: () => "two" };
var output = 'x is ' + x + ' while y is ' + y;
console.log(output); // writes "x is one while y is two" to the console

但是,在toString()Number的原型中覆盖Boolean时,未发现相同情况。强迫"强迫" toString()调用以获得所需的输出:

Number.prototype.toString = () => "42";
Boolean.prototype.toString = () => "whatever you wish";

var a = 1;
console.log('The answer is ' + a); // writes "The answer is 1"
console.log('The answer is ' + a.toString()); // writes "The answer is 42"

var b = true;
console.log('Girl you know it\'s ' + b); // writes "Girl you know it's true"
console.log('Girl you know it\'s ' + b.toString()); // writes "Girl you know it's whatever you wish"

这在浏览器中是一致的(在Chrome,Firefox和Edge上测试过),所以我认为它是标准行为。它在哪里记录?是否有在字符串连接期间获得特殊处理的标准对象列表?

2 个答案:

答案 0 :(得分:7)

JavaScript将在数字原语和数字对象之间自由转换。

如果你看rules for the + operator,你会看到它说:

  

7让lprim为ToPrimitive(lval)。

  

9让rprim为ToPrimitive(rval)。

因此,当处理+时,它将尝试使用对象上的基元。

然后有ToString rule将原语转换为字符串。

  

编号见7.1.12.1。

...然后描述a long special case

简而言之:

它将值转换为基元,然后具有将数字转换为字符串的特殊情况规则。

这意味着它不会将其视为对象或调用通常会覆盖此类规则的.toString方法。

答案 1 :(得分:3)

  1. Plus semantics

    • 如果Type(lprim)是String或Type(rprim)是String,那么
      • 让lstr成为?的ToString(lprim)。
      • 让rstr成为?的ToString(rprim)。
      • 返回lstr和rstr。
      • 的字符串连接
  2. ToString

    参数类型:Number =>返回NumberToString(参数)。

  3. NumberToString

    • 如果m是NaN,则返回String" NaN"。
    • 如果m为+0或-0,则返回String" 0"。
    • 如果m小于零,则返回" - "的字符串连接。而且!的ToString(-m)。
    • 如果m为+∞,则返回String" Infinity"。

    • ......你明白了。