![](/img/trans.png)
[英]Can any one explain me how does the string and number comparison work in javascript?
[英]Why does string to number comparison work in Javascript
我正在嘗試將來自 HTML 文本字段的值與整數進行比較。 它按預期工作。 條件是——
x >= 1 && x <= 999;
其中x
是文本字段的值。 只要值介於 1-999(含)之間,條件返回true
,否則返回false
。 問題是,來自文本字段的值是字符串類型,我將它與整數類型進行比較。 可以進行這樣的比較還是應該使用 parseInt() 將x
轉換為 integer ?
因為 JavaScript 定義>=
和<=
(以及其他幾個運算符)的方式允許它們將其操作數強制轉換為不同的類型。 它只是運算符定義的一部分。
在<
、 >
、 <=
和>=
的情況下,血淋淋的細節在規范的 §11.8.5 中列出。 簡短的版本是:如果兩個操作數都是字符串(在從對象中強制轉換之后,如有必要),它會進行字符串比較。 否則,它將操作數強制為數字並進行數字比較。
因此,您會得到有趣的結果,例如"90" > "100"
(兩者都是字符串,這是一個字符串比較)但"90" < 100
(其中一個是數字,這是一個數字比較)。 :-)
可以進行這樣的比較還是應該使用 parseInt() 將 x 轉換為 integer ?
這是一個見仁見智的問題。 有些人認為依靠隱含的強制是完全可以的; 其他人認為不是。 有一些客觀的論據。 例如,假設您依賴隱式轉換,這很好,因為您有那些數字常量,但后來您將x
與從輸入字段獲得的另一個值進行比較。 現在您正在比較字符串,但代碼看起來相同。 但同樣,這是一個見仁見智的問題,你應該做出自己的選擇。
如果您確實決定首先顯式轉換為數字,則parseInt
可能是也可能不是您想要的,並且它不會做與隱式轉換相同的事情。 以下是選項的概要:
parseInt(str[, radix])
- 盡可能多地將字符串的開頭轉換為一個整數(整數),忽略末尾的額外字符。 所以parseInt("10x")
是10
; x
被忽略。 支持可選的基數(數字基數)參數,因此parseInt("15", 16)
是21
(十六進制的15
)。 如果沒有基數,則假定為十進制,除非字符串以0x
(或0X
)開頭,在這種情況下,它會跳過這些並假定為十六進制。 不尋找新的0b
(二進制)或0o
(新式八進制)前綴; 這兩個都解析為0
。 (某些瀏覽器過去將字符串以0
開頭視為八進制;該行為從未指定,並且在 ES5 規范中[特別禁止][2]。)如果找不到可解析的數字,則返回NaN
。
Number.parseInt(str[, radix])
- 與上面的parseInt
完全相同的功能。 (從字面上看, Number.parseInt === parseInt
是true
。)
parseFloat(str)
- 與parseInt
類似,但處理浮點數且僅支持十進制。 字符串上的額外字符再次被忽略,因此parseFloat("10.5x")
為10.5
(忽略x
)。 由於僅支持十進制,因此parseFloat("0x15")
為0
(因為解析在x
處結束)。 如果沒有找到可解析的數字,則返回NaN
。
Number.parseFloat(str)
- 與上面的parseFloat
完全相同的函數。
一元+
,例如+str
- (例如,隱式轉換)使用浮點和 JavaScript 的標准數字表示法將整個字符串轉換為數字(只有數字和小數點 = 十進制; 0x
前綴 = 十六進制; 0b
= 二進制 [ES2015+]; 0o
前綴 = 八進制 [ES2015+];一些實現將其擴展為將前導0
視為八進制,但不是在嚴格模式下)。 +"10x"
是NaN
,因為x
未被忽略。 +"10"
是10
, +"10.5"
是10.5
, +"0x15"
是21
, +"0o10"
是8
[ES2015+], +"0b101"
是5
[ES2015+]。 有一個陷阱: +""
是0
,而不是您可能期望的NaN
。
Number(str)
- 完全像隱式轉換(例如,像上面的一元+
),但在某些實現上較慢。 (並不是說它可能很重要。)
與零按位或,例如str|0
- 隱式轉換,如+str
,但它還將數字轉換為 32 位整數(如果字符串無法轉換為有效數字,則將NaN
轉換為0
)。
因此,如果可以忽略字符串上的額外位,則parseInt
或parseFloat
都可以。 parseInt
對於指定基數非常方便。 一元+
對於確保考慮整個字符串很有用。 任你選擇。 :-)
對於它的價值,我傾向於使用這個功能:
const parseNumber = (str) => str ? +str : NaN;
(或修剪空白的變體。)注意它如何處理+""
為0
的問題。
最后:如果您要轉換為數字並想知道結果是否為NaN
,您可能會想這樣做if (convertedValue === NaN)
。 但這行不通,因為正如 Rick 在下面指出的那樣,涉及NaN
的比較總是錯誤的。 相反,它是if (isNaN(convertedValue))
。
MDN's docs on Comparision聲明操作數在比較之前轉換為通用類型(與您正在使用的運算符):
更常用的抽象比較(例如 ==)在進行比較之前將操作數轉換為相同的類型。 對於關系抽象比較(例如,<=),操作數首先轉換為基元,然后轉換為相同類型,然后再進行比較。
如果您使用的是嚴格比較,則只需要應用parseInt()
,在比較之前不會執行自動轉換。
如果 var 是字符串,則應使用parseInt
。 添加 = 來比較datatype
值:
parseInt(x) >== 1 && parseInt(x) <== 999;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.