为什么 JavaScript 会这样?
Why JavaScript behaves like that?
让我们看看这些例子:
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 会这样?
But why is object b gets converted to a string when there is no hint PreferredType.
当没有传递提示时,对象的valueOf
方法将首先被调用。但是由于 b.valueOf()
不是 return 原始值(默认情况下它 return 是对象本身),接下来将调用 b.toString()
。
转换规则可以总结如下:
- 如果没有提示或提示是
number
,先调用valueOf
。
- 如果提示是
string
,先调用toString
。
- 如果 return 值不是原始值,则调用其他方法。
- 如果 return 值仍然不是原始值,则抛出错误。
it is only gets converted to string if there is toString method exists on object, why?
不确定我是否理解此声明。每个对象都有一个 toString
方法。如果您尝试在没有 toString
方法(通过 Object.create(null)
)的对象上执行此操作,则会抛出错误。
And if I call that method "toNumber", why it is not converted to number?
因为toNumber
在JavaScript中没有意义。 toString
和 valueOf
是两个 "magic" 方法,通过它们将对象转换为基本类型:
var n = 1;
var o = {
toString() { return 'bar'; },
valueOf() { return 2; }
};
console.log(n + o);
console.log(String(o));
如果方法 none 中的 return 是原语,你也会得到一个错误。
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);
在调用 valueOf
或 toString
之前调用 @@toPrimitive
。
Why JavaScript behaves like that?
因为规范中就是这样定义的。如果你想知道这背后的理由,你必须问做出那个决定的人。
让我们看看这些例子:
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 会这样?
But why is object b gets converted to a string when there is no hint PreferredType.
当没有传递提示时,对象的valueOf
方法将首先被调用。但是由于 b.valueOf()
不是 return 原始值(默认情况下它 return 是对象本身),接下来将调用 b.toString()
。
转换规则可以总结如下:
- 如果没有提示或提示是
number
,先调用valueOf
。 - 如果提示是
string
,先调用toString
。 - 如果 return 值不是原始值,则调用其他方法。
- 如果 return 值仍然不是原始值,则抛出错误。
it is only gets converted to string if there is toString method exists on object, why?
不确定我是否理解此声明。每个对象都有一个 toString
方法。如果您尝试在没有 toString
方法(通过 Object.create(null)
)的对象上执行此操作,则会抛出错误。
And if I call that method "toNumber", why it is not converted to number?
因为toNumber
在JavaScript中没有意义。 toString
和 valueOf
是两个 "magic" 方法,通过它们将对象转换为基本类型:
var n = 1;
var o = {
toString() { return 'bar'; },
valueOf() { return 2; }
};
console.log(n + o);
console.log(String(o));
如果方法 none 中的 return 是原语,你也会得到一个错误。
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);
valueOf
或 toString
之前调用 @@toPrimitive
。
Why JavaScript behaves like that?
因为规范中就是这样定义的。如果你想知道这背后的理由,你必须问做出那个决定的人。