前端面试不能不说 toString valueOf

toString valueOf 方法

同步滚动:开

toString 方法返回 对象字符串

valueOf()方法:返回指定对象的原始值。

console.log(Math.abs.toString())
// "function abs() { [native code] } "
console.log(Math.abs.valueOf())
//ƒ abs() { [native code] }
console.log(Math)
// "[object Math]"

看下面这个奇怪的例子:

你是不是觉得很奇怪啊,对象可以直接相加

是不是特别奇怪

其实在运算和输出的时候就是调用 valueOf() 和 toString() 方法了

 var aaa = {
i: 10,
valueOf: function() {
console.log('hello valueOf')
return this.i+30;
},
toString: function() {
console.log('hello toString')
return this.valueOf()+10;
}
}
console.log(aaa > 20); // hello valueOf true
console.log(''+aaa); //hello valueOf 40
console.log(aaa==12); //hello valueOf false
console.log(String(aaa)) //hello toString hello valueOf 50

下面是一个面试题,需要输出hello world

var a = {
value:1,
// valueOf:function(){
// console.log('valueOf')
// return this.value++;
// },
toString:function(){
console.log('tostring')
return this.value++;
}
}
if(a==1&&a==2&a==3){
console.log("hellow world")
}
/*
如果是这样子是否可以输出hello world 呢?
if(a===1&&a===2&a===3){
console.log("hellow world")
}
*/
// 不行的=== 是隐式转换来的无法调用这两个方法。

通过这些例子可以看出区别:

如果只重写了toString,对象转换时会无视valueOf的存在来进行转换。但是,如果只重写了valueOf方法,在要转换为字符串的时候会优先考虑valueOf方法。

在不能调用toString的情况下,只能让valueOf上阵了。

对于那个奇怪的字符串拼接问题,可能是出于操作符上,翻开ECMA262-5 发现都有一个getValue操作。嗯,那么谜底应该是揭开了。

重写会加大它们调用的优化高,而在有操作符的情况下,valueOf的优先级本来就比toString的高。

总结:

1.没有运算符的情况下

优先级从最高到最低依次是:

Object.prototype.toString、Object.prototype.valueOf、最后才是重写的valueOf

2.有运算符时还是重写的valueOf优先级最高

3.String()时

见上例alert(String(bb));,

优先级依次是

Object.prototype.toString、

重写的valueOf、 Object.prototype.valueOf


分享到:


相關文章: