前端面試不能不說 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


分享到:


相關文章: