簡體   English   中英

為什么字符串到數字的比較在 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 === parseInttrue 。)

  • 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 )。

因此,如果可以忽略字符串上的額外位,則parseIntparseFloat都可以。 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.

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