你真的理解==和===嗎

開門見題

說出如下幾個表達式的結果javascript

var obj1 = { name: '張三'}
var obj2 = obj1
var obj3 = { name: '張三'}

null == undefined
123 == '123'
false == 0
NaN == false
obj1 == obj2
obj1 == obj3

補充知識

要想回答上述問題,必須理解js在執行==時候的一些數據轉換規則和成文的規定。ECMA-262對==的約定以下:
2762?ynotemdtimestamp=1532482432857java

x==y

  1. 若是x和y的類型相同,函數

    1. 若是x是undefined,return true
    2. 若是x是null,return true
    3. 若是x是Numberspa

      1. x是NaN,return false
      2. y是NaN,return false
      3. x,y數值相同,return true
      4. x是+0,y是-0,return true
      5. x是-0,y是+0,return true
    4. 若是x是String,y必須和x長度內容都相同才return true,不然return false
    5. 若是x是Boolean,x,y相同return true,不然return false
    6. 若是x,y引用同一個對象,return true,不然return false
  2. x是null,y是undefined,return true
  3. x是undefined,y是null,return true
  4. x是Number,y是String,return x == ToNumber(y)
  5. x是String,y是Number,return ToNumber(x) == y
  6. x是Boolean,return ToNumber(x) == y
  7. y是Boolean,return x == ToNumber(y)
  8. x是String或Number,y是Object,return x == ToPrimitive(y)
  9. x是Object,y是String或Number,return ToPrimitive(x) == y
  10. return false

你可能注意到了這樣兩個函數3d

ToNumber()

參數類型 結果
Undefined NaN
Null +0
Boolean true爲1,false爲+0
Number 參數自己
String 簡單理解,能轉換成數字的就會轉換成數字,好比數字字符串,十六進制的數字等,轉換失敗則返回NaN(詳見ECMA-262-9.3.1,內容較多,不展開敘述)
Object 兩步轉換操做:1. ToPrimitive(input argument, hint Number) 2. ToNumber()

ToPrimitive()

參數類型 結果
Undefined 輸入值
Null 輸入值
Boolean 輸入值
Number 輸入值
String 輸入值
Object 調用DefaultValue方法

好吧,又多了一個DefaultValue方法code

ToPrimitive()

細心的你發現上面ToNumber對於Object的轉換裏有這麼一句ToPrimitive(input argument, hint Number),就是說調用ToPrimitive的時候,除了傳入要轉化的值,還傳了一個hint參數,這個參數能夠爲Number,也能夠爲String。那麼何時傳入這兩個參數,同時又有啥區別?對象

  • 若是參數是hint Number:
  1. 先執行valueOf,若是返回值是原始值,則返回原始值
  2. 不然執行toString,若是返回值是原始值,則返回原始值
  3. 報錯
  • 若是參數是hint String:
  1. 先執行toString,若是返回值是原始值,則返回原始值
  2. 不然執行valueOf,若是返回值是原始值,則返回原始值
  3. 報錯

若是input argument是內置的Date類型,則參數是hint String,不然默認hint Numberblog

回到題目

說了這麼多,咱們回到上面的題目,一一解答:ip

  1. null == undefined。根據上面第二條,寫的明明白白,結果是true。
  2. 123 == '123'。根據上面第四條return 123 == ToNumber('123'),而ToNumber('123')的結果爲123,因此return 123 == 123,根據1-3-3,返回true。
  3. false == 0。根據上面第六條,return ToNumber(false) == 0,而ToNumber(false)的值爲+0,因此+0 == 0,根據1-3-3,返回true。
  4. NaN == false。看到不少別的同窗說這裏是作了各類類型轉換,其實我認爲這裏是因爲沒有匹配到任何規則,因此根據第十條返回false,也就是說並無作什麼類型轉換。
  5. obj1 == obj2。根據1-6,因爲obj1和obj2指向同一個引用,因此返回true。
  6. obj1 == obj3。根據1-6,因爲obj1和obj2指向不一樣引用,因此返回false。

關於===

把上面題目中的==換成===,試問結果會發生怎樣的變化?這裏我就不說了,推理方式同上,根據以下規則,答案請各位看官自行補充。
2934?ynotemdtimestamp=1532482432857字符串

x===y

  1. 若是x,y類型不一樣,return false
  2. 若是x是undefined,return true
  3. 若是x是null,return true
  4. 若是x是Number

    • 若是x是NaN,return false
    • 若是y是NaN,return false
    • x,y數值相同,return true
    • x是+0,y是-0,return true
    • x是-0,y是+0,return true
    • return false
  5. 若是x是String,y必須和x長度內容都相同才return true,不然return false
  6. 若是x,y引用同一個對象,return true,不然return false
相關文章
相關標籤/搜索