借鑒與老師寫的一篇文章,原文地址:http://www.itdecent.cn/p/25001441ffba
變量a在什么情況下會滿足這三個條件,打印出1?
var a = ?
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
解題:
var a = {
i: 1,
toString: function() {
return a.i ++;
}
}
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
思路:
1、JavaScript對象在與 字符串拼接或者比較 時,首先會通過valueOf()方法獲取其原始值。原始值就是其本身。
var a = {};
console.log(a.valueOf()); // {}
console.log(a === a.valueOf()); // true
2、如果valueOf值為對象,則會去調(diào)用對象的toString()方法。若該對象內(nèi)部沒有重寫實現(xiàn)該方法,會調(diào)用對象共有的toString()方法,返回"[object Object]"。
var a = {};
console.log(a.toString()); // [object Object] 類型為string
console.log(a.toString() + 1); // [object Object]1 返回結(jié)果為字符串,拼接1
console.log(a + 1 === a.toString() + 1); // true;
3、如果對象下有重寫toString()方法,會執(zhí)行該方法:
var a = {
toString() {
return 1;
}
}
console.log(a.toString()); // 1
console.log(a.toString() - 1); // 0
console.log(a - 1 === a.toString() - 1); // true 進行比較對象a會執(zhí)行valueOf()和toString()方法。
4、以上可以看出對象每進行一次比較或拼接都會執(zhí)行toString()方法。
var num =1;
var a = {
toString(){
return ++num;
}
};
console.log(a + "");// 2
console.log(a + "");// 3
console.log(a + 1);// 5
console.log(a == 5);// true
5、最終實現(xiàn)結(jié)果:
// 使用 toString 實現(xiàn):
var a = {
i: 1,
toString: function() {
return a.i ++;
}
}
// a == 1 比較時,a對象會調(diào)用toString()方法,返回結(jié)果與1進行比較。
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
// 使用 valueOf 實現(xiàn):
let a = {
i: 0,
valueOf: function() {
return ++ a.i;
}
}
if (a == '1' && a == '2' && a == '3') {
console.log(typeof obj); // object
}
注意:不論是 toString 方法或者是 valueOf 方法實現(xiàn), 都不可以使用全等去判斷a,因為此時a的類型為對象。