看見這個面試題目,第一反應就是在變量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 ()}
以上是關於這個問題的兩種思路,當然還有還有我不知道的其他的做法,以後再補充