簡體   English   中英

使用==比較整數和字符串時JavaScript中的隱式數據類型轉換

[英]Implicit data type conversion in JavaScript when comparing integer with string using ==

代碼:

var num = 20;

if(num == "20")
{
    alert("It works");
}
else
{
    alert("Not working");
}

問題:

  1. 在C編程中,我們有一個規則名稱數據類型提升,當存在混合數據類型時(例如:添加整數和浮點),整數將在執行加法之前首先轉換為浮點。

  2. 上面的代碼將提示我一個警告框,其中顯示"It works"消息,顯示if測試條件是否為true。

  3. 對於松散類型的JavaScript,我只是好奇:有沒有像C這樣的規則決定在哪種情況下執行轉換? 除此之外,上面的JavaScript代碼在進行比較之前將num變量值從整數值轉換為字符串值,反之亦然?

是的,equals運算符應用的所有類型轉換規則都在ECMA-262規范的抽象等式比較算法中描述

該算法看起來可能非常復雜,但可歸納為以下情況:

  1. 兩個操作數的類型是相同的:

    • 對於基元(String,Number,Boolean,Null,Undefined)
      • 如果值完全相同,則返回true
    • 對於Object類型
      • 如果兩個引用指向同一個對象,則返回true
  2. 如果兩個操作數的類型不同

    • 如果一個操作數的類型是Null或Undefined
      • 僅當其他操作數值為nullundefined時才返回true
    • 如果其中一個操作數的類型為Boolean或Number
      • (在一些步驟之后)將另一個操作數轉換為Number並進行比較
  3. 如果其中一個操作數是Object而另一個是原語

    • 在Object上執行Object-to-Primitive轉換並再次進行比較

Object-to-Primitive轉換是通過名為ToPrimitive的抽象操作ToPrimitive ,此方法將嘗試使用內部[[PrimitiveValue]]方法將對象轉換為原始值。

這將嘗試執行對象的valueOftoString方法,它將獲取返回原始值的第一個值。

如果這兩個方法沒有返回原語,或者它們不可調用,則拋出TypeError ,例如:

1 == { toString:null } // TypeError!

上面的語句將產生一個TypeError因為默認的Object.prototype.valueOf方法除了實際上相同的對象實例( this不是原始值)之外什么都不做,我們正在設置一個自己的toString屬性,它不是一個函數。

一個朋友制作了一個可能對你感興趣的小工具,它顯示了所有步驟和類型之間的遞歸比較:

在JavaScript中,有兩個運算符可用於比較兩個值: =====運算符。

引自JavaScript The Definitive Guide第6版:

等於運算符==就像嚴格相等運算符( === ),但它不那么嚴格。 如果兩個操作數的值不是同一類型,它會嘗試某些類型轉換並再次嘗試比較。

嚴格相等運算符===計算其操作數,然后按如下方式比較這兩個值,不執行類型轉換。

所以我建議你一直使用===來避免以下問題:

null == undefined // These two values are treated as equal. 
"0" == 0 // String converts to a number before comparing. 
0 == false // Boolean converts to number before comparing. 
"0" == false // Both operands convert to numbers before comparing.

PS我可以發布書中所寫的整個“比較指南”,但它太長了;)告訴我,我會為你編輯我的帖子。

避免在JavaScript中進行隱式類型轉換。 在比較之前,請始終采取措施測試和/或轉換單個值,以確保您將蘋果與蘋果進行比較。 始終顯式測試undefined以確定值或屬性是否具有值,使用null指示對象變量或屬性不引用任何對象,並轉換和比較所有其他值以確保對相同類型的值執行操作。

我知道問題已得到解答。 我在下面給出的是幾個轉換的例子。 對於剛接觸JavaScript的人來說,這將非常有用。 以下輸出可以與通用算法進行比較,以便於理解。

代碼:

var values = ["123",
          undefined,
          "not a number",
          "123.45",
          "1234 error",
          "",
          "       ",
          null,
          undefined,
          true,
          false,
          "true",
          "false"
          ];

for (var i = 0; i < values.length; i++){
    var x = values[i];
    console.log("Start");
    console.log(x);
    console.log(" Number(x) = " + Number(x));
    console.log(" parseInt(x, 10) = " + parseInt(x, 10));
    console.log(" parseFloat(x) = " + parseFloat(x));
    console.log(" +x = " + +x);
    console.log(" !!x = " + !!x);
    console.log("End");
}

輸出:

"Start"
"123"
" Number(x) = 123"
" parseInt(x, 10) = 123"
" parseFloat(x) = 123"
" +x = 123"
" !!x = true"
"End"

"Start"
undefined
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = false"
"End"

"Start"
"not a number"
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = true"
"End"

"Start"
"123.45"
" Number(x) = 123.45"
" parseInt(x, 10) = 123"
" parseFloat(x) = 123.45"
" +x = 123.45"
" !!x = true"
"End"

"Start"
"1234 error"
" Number(x) = NaN"
" parseInt(x, 10) = 1234"
" parseFloat(x) = 1234"
" +x = NaN"
" !!x = true"
"End"

"Start"
""
" Number(x) = 0"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 0"
" !!x = false"
"End"

"Start"
"       "
" Number(x) = 0"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 0"
" !!x = true"
"End"

"Start"
null
" Number(x) = 0"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 0"
" !!x = false"
"End"

"Start"
undefined
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = false"
"End"

"Start"
true
" Number(x) = 1"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 1"
" !!x = true"
"End"

"Start"
false
" Number(x) = 0"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 0"
" !!x = false"
"End"

"Start"
"true"
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = true"
"End"

"Start"
"false"
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = true"
"End"

更好地使用下面的代碼來理解隱式轉換。

 var values = [ 0 , 123, "0", "123", -0, +0, NaN, +NaN, -NaN, false, true, "false", "true", null, undefined, "null", "undefined", "", "GoodString", " "]; for (var i = 0; i < values.length; i++){ console.log("<<<<<<<<<<<<Starting comparing: " + i + ">>>>>>>>>>>>>>>"); for (var j = 0; j < values.length; j++){ console.log(values[i],`==`, values[j]); console.log(eval(values[i] == values[j])); } } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM