看見這個面試題目,第一反應就是在變數a
取值時進行了一些改變,那就要用getter
,關於存取器的介紹可以看這裡
var temp = 1;
Object.defineProperty(window, `a`, {
get: function() { // 每次取值,temp+1
return this.temp++
}
});
console.log( a === 1 && a === 2 && a === 3); // true
console.log(a) // 4
同樣的問題是使 (a == 1 && a == 2 && a == 3)
返回true
,不同點是,這裡是==
,而不再是===
。
===
恆等運算子在比較過程中,不會有任何型別轉換;
==
相等運算子比較寬鬆,如果兩個運算元不是同一型別,那麼相等運算子會嘗試進行一些型別轉換,然後進行比較。轉換規則如下:
- 如果一個是
null
,一個是undefined
,則它們相等 - 如果一個是
數字
,一個是字串
,先將字串轉換成數字,然後使用轉換後的值進行比較 - 如果其中的一個值為
true
,則轉換成1
再進行比較;如果其中一個值為false
,這轉換成0
再進行比較 - 如果一個值是物件,另一個值是數字或者字串,則將物件轉換成原始值再進行比較。轉換成字串時,會先呼叫
toString()
,如果沒有toString()
方法或者返回的不是一個原始值,則再呼叫valueOf()
,如果還是不存在或者返回不是原始值,則會丟擲一個型別錯誤的異常。返回的原始值會被轉換成字串;如果轉換成數字時,也是類似的,不過是會先呼叫valueOf()
,再呼叫toString()
,返回的原始值會被轉換成數字 - 其他不同型別之間的比較均不相等
更詳細的資料型別轉換可以看 這裡
回到題目中,除了第一種使用getter
的思路外,可以將a作為一個物件,而它的在比較中會轉換成數字,所以可以重寫valueOf()
方法,在每次取值的時候,進行一些處理。
let a = {
temp:1,
valueOf:function(){
return this.temp++
}
}
console.log(a == 1 && a == 2 && a == 3); // true
console.log(a) {temp:4,valueOf: f ()}
以上是關於這個問題的兩種思路,當然還有還有我不知道的其他的做法,以後再補充