如何讓表達式(a ==1 && a== 2 && a==3)等於true?

點擊右上方紅色按鈕關注“小鄭搞碼事”,每天都能學到知識,搞懂一個問題!

突然看到這一個這樣的問題,感覺這個問題比較有意思,看似一道毫無"價值"的題(因為我在日常工作代碼中從來不寫這樣的代碼),但是,通過分析這道題,確實也能順便複習幾個基礎知識點和JS的執行機制。

這道題解決的關鍵點有可能是因為它用的是相等符(==),而不是全等符(===,全等的關鍵是數據類型也得一樣)。想了一下,有以下幾個解決方案的思路還是很容易想到的。

第一種方案:利用對象返回

我們可以創建一個帶有自定義valueOf方法(或者toString方法)函數的對象,每次使用時,改變它的返回值。如下代碼:

如何讓表達式(a ==1 && a== 2 && a==3)等於true?

上面代碼輸出:小鄭搞碼!

為什麼會輸出:小鄭搞碼!?在if條件判斷中,我們使用的是相等符(==),相等符比較的目標操作數類型可以不同,所以在比較的時候,如果其中一個操作數與另一個類型不同,則 JS 引擎會嘗試將一個操作轉換為另一個類型。

就上面我寫的這段代碼而言,兩個比較操作符,右邊是數字,左邊是一個對象的情況下,會將對象轉換成一個數,對象轉成成數的方式就是,對象會去調用它的valueOf方法(valueOf是可以調用的),若valueOf不可調用則會自動調用toString方法得到一個字符串,然後,JS引擎在嘗試將字符串轉成數字進行比較。

上面if條件判斷代碼中,每判斷一次,a的值會自動加1。所以判斷a等於1,2,3,4......與運算後都會返回true。有疑問者,可以自行運行代碼驗證一下。

第二種方案:ECMAScript解釋空格為標識符

這第二個方案,就得記住了,因為它簡單好理解,但一般人不容易想到。

來看一段代碼:

如何讓表達式(a ==1 && a== 2 && a==3)等於true?

上面這段代碼輸出:true。

請注意,第一個a變量後面那個奇怪的間距。你可以認為它是一個普通的空格,從上面代碼輸出結果看,ECMAScript不會將其解釋為一個空格。這就意味著它是一個有效的標識符。因此,上面是兩個完全不同的變量。就好比將空格換成一個下劃線。

如何讓表達式(a ==1 && a== 2 && a==3)等於true?

輸出:true。

知道這一點後,現在,我們來解決一下題目的問題。

如何讓表達式(a ==1 && a== 2 && a==3)等於true?

輸出:小鄭搞碼!

第三種方案:JavaScript對象劫持

使用對象劫持,關於JavaScript對象劫持想了解更多的,可以翻一下之前我寫的文章。這裡,來看一下,使用對象劫持怎麼解決題目中的問題。

如何讓表達式(a ==1 && a== 2 && a==3)等於true?

使用一個get方法,讓 a 的返回值為三個不同的值,這個邏輯思路有點類似於第一種方案,也很好理解,在實際項目代碼中,並不推薦這麼搞。

最後總結一下:

對於方案一,其實主要是利用了相等的原理,需要注意對象的比較情況。

對於方案二,像是一種障眼法,本質上還是和題目有些差別的。

對於方案三,利用JS劫持,改變了get方法。這種方式對於全等也是有效的。


分享到:


相關文章: