以下所示:前端
問: a等於多少時, 下方的條件才成立 var a = ?; if (a == 1 && a == 2 && a == 3) { console.log(1) }
這題比較有意思啊,相信不少前端同窗都看過。它的解法有不少,本篇列出我所知道的幾種方式。
不少人第一眼看到這道題可能會認爲a=true
時,便可知足。可是並不對。由於==
雙等號在比較時, 會進行隱式類型轉換
。在轉換時分幾種狀況:數組
1 .對象 == 字符串
會調用對象的toString()
方法後 和字符串作比較
對象.toString() == string
2 .null == undefined
只有在雙等號狀況下才是true
3 .
NaN == NaN
NaN和任何數據 包括它本身都不相等
返回falsethis4 . 剩餘狀況
剩下的比較都會轉換爲數字再進行比較
code因此說 將
a=true
並不能知足條件。由於true
轉換爲數字爲1
,那麼1 == 1
可是1 !== 2
和1 !== 3
對象
因此得想其餘方法
字符串
重寫對象內部的.toString()方法
var a = { _key: 0, toString() { return ++this._key } } if (a == 1 && a == 2 && a == 3) { console.log(1) } // 打印結果 // 1
以上代碼成功打印結果1
。該方法利用了對象轉換爲數值
過程當中會先調用對象內部的toString()
方法。 咱們對toString()
方法進行重寫,經過一個_key
來保存每次累加的結果
。每調用一次重寫後的toString()
方法_key
值都會+1
。即知足if條件。get
將toSting()方法重寫爲數組的shift()方法
var a = [1,2,3]; a.toString = a.shift; if (a == 1 && a == 2 && a == 3) { console.log(1) } // 打印結果 // 1
其實該方法也是重寫了toString()
方法。只不過將toString()
重寫爲了數組的shift()
方法。shift方法刪除數組的第一項並返回該項
。數組轉數值
的過程當中也會調用toString()
方法,由於a.toString = a.shift
,因此每次調用的都是shift()
方法。每次都會刪除數組的第一項並返回
,保證每次toString()的返回值都不同
。string
數據劫持
Object.defineProperty()
var temp = 0; Object.defineProperty(window, 'a', { get() { // 此處注意 在get攔截器中 不能獲取當前屬性a // 否則會形成死循環 報錯 return ++temp; } }) if (a == 1 && a == 2 && a == 3) { console.log(1) } // 打印結果 // 1
相似ES6中proxy
,使用ES5中的defineProperty
去監聽obj中的name屬性
。使用一個臨時變量temp
來累加,每次只要監聽a
都會返回累加後的值。固然也是有缺點,若是是經過let 聲明
的變量就不能用該方法了,由於let聲明的變量並無放到window上
,因此也無從監聽。