[英]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");
}
問題:
在C編程中,我們有一個規則名稱數據類型提升,當存在混合數據類型時(例如:添加整數和浮點),整數將在執行加法之前首先轉換為浮點。
上面的代碼將提示我一個警告框,其中顯示"It works"
消息,顯示if
測試條件是否為true。
對於松散類型的JavaScript,我只是好奇:有沒有像C這樣的規則決定在哪種情況下執行轉換? 除此之外,上面的JavaScript代碼在進行比較之前將num
變量值從整數值轉換為字符串值,反之亦然?
是的,equals運算符應用的所有類型轉換規則都在ECMA-262規范的抽象等式比較算法中描述 。
該算法看起來可能非常復雜,但可歸納為以下情況:
兩個操作數的類型是相同的:
如果兩個操作數的類型不同
null
或undefined
時才返回true 如果其中一個操作數是Object而另一個是原語
Object-to-Primitive轉換是通過名為ToPrimitive
的抽象操作ToPrimitive
,此方法將嘗試使用內部[[PrimitiveValue]]
方法將對象轉換為原始值。
這將嘗試執行對象的valueOf
和toString
方法,它將獲取返回原始值的第一個值。
如果這兩個方法沒有返回原語,或者它們不可調用,則拋出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.