關於如何使`(a === 1 && a === 2 && a === 3)`返回`true`問題的思考

看見這個面試題目,第一反應就是在變量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,不同點是,這裏是==,而不再是===

===恆等運算符在比較過程中,不會有任何類型轉換
==相等運算符比較寬鬆,如果兩個操作數不是同一類型,那麼相等運算符會嘗試進行一些類型轉換,然後進行比較。轉換規則如下:

  1. 如果一個是null,一個是undefined,則它們相等
  2. 如果一個是數字,一個是字符串,先將字符串轉換成數字,然後使用轉換後的值進行比較
  3. 如果其中的一個值爲true,則轉換成1再進行比較;如果其中一個值爲false,這轉換成0再進行比較
  4. 如果一個值是對象,另一個值是數字或者字符串,則將對象轉換成原始值再進行比較。轉換成字符串時,會先調用toString(),如果沒有toString()方法或者返回的不是一個原始值,則再調用valueOf(),如果還是不存在或者返回不是原始值,則會拋出一個類型錯誤的異常。返回的原始值會被轉換成字符串;如果轉換成數字時,也是類似的,不過是會先調用valueOf(),再調用toString(),返回的原始值會被轉換成數字
  5. 其他不同類型之間的比較均不相等

更詳細的數據類型轉換可以看 這裏

回到題目中,除了第一種使用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 ()}

以上是關於這個問題的兩種思路,當然還有還有我不知道的其他的做法,以後再補充

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章