a == 1 && a == 2 && a == 3

js中有7種數(shù)據(jù)類型,可以分為兩類:

  • 基礎(chǔ)類型(原始值):
    Undefined、 NullString、 Number、Boolean、 Symbol(es6新出的)
  • 復(fù)雜類型(對(duì)象值):
    object

什么情況下能正確打印‘success’?

var  a = ???
if(a == 1 && a == 2 && a == 3 ){
    console.log('success')
}
  1. 關(guān)系運(yùn)算符:會(huì)把其他數(shù)據(jù)類型轉(zhuǎn)換成number之后再比較關(guān)系
  2. 首先我們排除掉原始數(shù)據(jù)類型(Undefined、Null、Boolean、Number 和 String、Symbol),a應(yīng)該是個(gè)復(fù)雜數(shù)據(jù)類型
  3. 復(fù)雜數(shù)據(jù)類型在隱式轉(zhuǎn)換時(shí)會(huì)利用valueOftoString,然后再轉(zhuǎn)成Number運(yùn)算(valueOf和toString是所有對(duì)象原型鏈頂層原型Object.prototype里的方法,所以每個(gè)對(duì)象都繼承這兩方法)

由此得知,我們可以重寫復(fù)雜數(shù)據(jù)類型在隱式轉(zhuǎn)換過程中所涉及的方法來達(dá)到效果

// 方法1
var a = {
    i: 0,
    valueOf() { // 這里的valueOf()也可以替換成toString()
        return ++this.i
    }
}
if(a == 1 && a == 2 && a == 3 ){
    console.log('success')
}

// 方法2
var a = {
    arr: [3, 2, 1],
    valueOf() { // 這里的valueOf()也可以替換成toString()
        return this.arr.pop()
    }
}
if (a == 1 && a == 2 && a == 3) {
  console.log('success')
}

在隱式轉(zhuǎn)換為number時(shí),執(zhí)行以下流程:

1、如果當(dāng)前值已經(jīng)是一個(gè)原始類型,則直接返回它
2、否則,如果當(dāng)前值是一個(gè)對(duì)象,則先調(diào)用valueOf()方法,如果結(jié)果是原始類型則直接返回
3、否則,調(diào)用這個(gè)對(duì)象的toString()方法,如果結(jié)果是原始類型,則返回toString()結(jié)果
4、否則,拋出TypeError異常

具體隱式轉(zhuǎn)換規(guī)則可參考here

  1. 所以上題在運(yùn)行時(shí)會(huì)先判斷 a 的類型,此時(shí)typeof a('object'),不是原始類型,因此會(huì)先調(diào)用a.valueOf()
  2. 由于我們重寫了valueOf(),因此會(huì)執(zhí)行重寫后的valueOf(),每一次都會(huì)(得到自增后的值)or(返回a.arr的尾元素,并更新a.arr),結(jié)果是原始類型所以不會(huì)再繼續(xù)調(diào)用toString()
  3. 得出三次執(zhí)行結(jié)果為 1, 2, 3, 滿足條件

~~歡迎交流指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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