(a== 1 && a ==2 && a==3)可能為true嗎?

前言

  • 最近在網(wǎng)上看到一個(gè)面試題:(a== 1 && a ==2 && a==3)有可能返回true嗎?答案是可以的,下面來具體講解一下。

valueOf和toString

  • 這個(gè)問題的一個(gè)關(guān)鍵點(diǎn)就是在于利用==雙等號工作原理,=====有什么區(qū)別呢?最主要的就是用==的時(shí)候會涉及到類型轉(zhuǎn)換,如果雙等號兩邊數(shù)據(jù)類型不同會嘗試將他們轉(zhuǎn)化為同一類型?;A(chǔ)數(shù)據(jù)類型之間的轉(zhuǎn)換是比較簡單的,這里來說一下對象類型在使用==時(shí)產(chǎn)生的隱形轉(zhuǎn)換。

  • valueOf和toString這兩個(gè)方法是每個(gè)對象都自帶的(繼承自O(shè)bject原型),我們先定義一個(gè)簡單的對象然后調(diào)用他的這兩個(gè)方法來看下結(jié)果:

    image
  • 可以看到toString返回一個(gè)字符串"[object Object]",valueOf則是直接返回對象本身,而c=="[object Object]"也為true則說明了在隱式轉(zhuǎn)換的過程中,調(diào)用了c的toString方法。

實(shí)現(xiàn)

  • 到這里我們只要重新定義一下變量a,重寫它的toString方法就可以實(shí)現(xiàn)我們要達(dá)到的目的了:
let a = {
  i: 1,
  toString () {
    return a.i++
  }
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}
// 輸出Hello World!

  • 這里說下具體的過程:執(zhí)行a==1時(shí),js引擎會嘗試把對象類型a轉(zhuǎn)化為數(shù)字類型,首先調(diào)用a的valueOf方法來判斷,不行則繼續(xù)調(diào)用toString方法,然后再把toString返回的字符串轉(zhuǎn)化為數(shù)字類型再去和a作比較(這里我重寫了toString就直接返回的數(shù)字類型的結(jié)果,正常情況toString返回的字符串)。
  • 所以每一次使用==判斷都會調(diào)用一次a的toString方法,返回i屬性的值,然后使a的i屬性加1,這樣最后的判斷結(jié)果自然就為true了。
  • 其實(shí)重寫valueOf方法也可以實(shí)現(xiàn),而且轉(zhuǎn)化時(shí)會優(yōu)先調(diào)用valueOf方法:
var c = {
  toString () {
    console.log('toString')
  },
  valueOf () {
    console.log('valueOf')
  }
}
c == 1
// console輸出'valueOf'

結(jié)語

  • 這個(gè)問題看起來是解決了,但其實(shí)在實(shí)際項(xiàng)目中去重寫原生對象的toStringvalueOf方法是很不應(yīng)該的,比如toString本來是一定會返回一個(gè)字符串結(jié)果的,重寫后返回其他類型反而容易出問題。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容