我知道当JS尝试将对象表示为原始对象时,它会调用valueOf对象上的方法.但今天我发现它也在toString()同样的情况下调用方法:
var o = {};
o.toString = function() {return 1};
1+ o; // 2
Run Code Online (Sandbox Code Playgroud)
为什么?如果我添加valueOf方法则toString不会被调用.
Eri*_*AND 10
我想这个解释在ECMA-262规范的 8.6.2.6章节中:
8.6.2.6 [DefaultValue]
[...]
使用提示号调用O的[[DefaultValue]]方法时,将执行以下步骤:
使用参数"valueOf"调用对象O的[[Get]]方法.
如果Result(1)不是对象,请转到步骤5.
如果Result(3)是原始值,则返回Result(3).
使用参数"toString"调用对象O的[[Get]]方法.
如果Result(5)不是对象,请转到步骤9.
由于您的对象未实现valueOf,因此使用toString.
这一切都取决于提示.当你使用1 + o它是一个数字提示因为+操作数所以它肯定会使用valueOf之前toString.
如果提示是String,则toString之前使用valueOf.例如试试["o",o].join("=")
一起将是:
var o = {};
o.toString = function() {return 1};
o.valueOf= function(){return 2};
1 + o; // 1+2=3 ==> it takes valueOf value
["o",o].join("") //o1 ==> it takes toString value
Run Code Online (Sandbox Code Playgroud)
TL; DR
当调用ToPrimitive时,hint它的行为就像提示一样number.定义要调用的方法:第一valueOf,然后toString.如果你还没有定义自己的,valueOf那么它会调用Object.prototype.valueOf它返回.
BTW在现代浏览器中你可以更具体地了解它
const a = {
[Symbol.toPrimitive]: function(hint) {
console.log(hint);
return {
'default': 1,
'number': 2,
'string': 'three'
}[hint]
}
}
console.log(a + 1); //default, 2
console.log(+a + 1); //number, 3
console.log(`${a} + one`); //string, three + one
Run Code Online (Sandbox Code Playgroud)
长读:
| 归档时间: |
|
| 查看次数: |
617 次 |
| 最近记录: |