วิธีการ (ในตัว) ใน JavaScript เพื่อตรวจสอบว่าสตริงเป็นจำนวนที่ถูกต้อง


1190

ฉันหวังว่าจะมีบางสิ่งในพื้นที่แนวคิดเดียวกันกับIsNumeric()ฟังก์ชันVB6 เดิมหรือไม่


3
ดูคำถามที่เกี่ยวข้องซึ่งฉันถามบางเวลาที่ผ่านมา
Michael Haren

38
หากคุณไปที่คำถามนี้พยายามข้ามคำตอบทั้งหมดของ RegEx นั่นไม่ใช่วิธีที่จะทำ
Joel Coehoorn

14
ถ้าไม่มีใครอยากทำอย่างนั้น: เพื่อตรวจสอบว่าสตริงที่กำหนดมีรูปแบบของกระแสหลักที่ถูกต้อง ทำไมมันจึงผิด
SasQ

17
คำตอบที่เลือกไม่ถูกต้อง !!! ดูความคิดเห็นของตน แต่โดยทั่วไปจะล้มเหลวด้วยเช่นisNaN(""), isNaN(" "), isNaN(false)ฯลฯ ผลตอบแทนfalseเหล่านี้หมายความว่าพวกเขาจะมีตัวเลข
แอนดรู

1
ดังนั้นคำตอบที่เลือกไม่ถูกต้อง regexp ไม่ใช่วิธีการทำเช่นนั้น อันไหนที่ถูกต้องแล้ว?
vir us

คำตอบ:


2323

ในการตรวจสอบว่าตัวแปร (รวมถึงสตริง) เป็นตัวเลขหรือไม่ให้ตรวจสอบว่าไม่ใช่ตัวเลขหรือไม่:

สิ่งนี้ใช้ได้ผลไม่ว่าเนื้อหาตัวแปรจะเป็นสตริงหรือตัวเลข

isNaN(num)         // returns true if the variable does NOT contain a valid number

ตัวอย่าง

isNaN(123)         // false
isNaN('123')       // false
isNaN('1e10000')   // false (This translates to Infinity, which is a number)
isNaN('foo')       // true
isNaN('10px')      // true

แน่นอนคุณสามารถปฏิเสธได้หากคุณต้องการ ตัวอย่างเช่นในการใช้IsNumericตัวอย่างที่คุณให้:

function isNumeric(num){
  return !isNaN(num)
}

ในการแปลงสตริงที่มีตัวเลขเป็นตัวเลขให้ทำดังนี้

ทำงานเฉพาะถ้าสตริงเท่านั้นNaNประกอบด้วยอักขระตัวเลขผลตอบแทนมันอื่น

+num               // returns the numeric value of the string, or NaN 
                   // if the string isn't purely numeric characters

ตัวอย่าง

+'12'              // 12
+'12.'             // 12
+'12..'            // NaN
+'.12'             // 0.12
+'..12'            // NaN
+'foo'             // NaN
+'12px'            // NaN

ในการแปลงสตริงให้หลวมเป็นตัวเลข

มีประโยชน์สำหรับการแปลง '12px' เป็น 12 เช่น:

parseInt(num)      // extracts a numeric value from the 
                   // start of the string, or NaN.

ตัวอย่าง

parseInt('12')     // 12
parseInt('aaa')    // NaN
parseInt('12px')   // 12
parseInt('foo2')   // NaN      These last two may be different
parseInt('12a5')   // 12       from what you expected to see. 

ลอยตัว

จำไว้ว่าไม่เหมือน+num, parseInt(เป็นชื่อแนะนำ) จะแปลงลอยเป็นจำนวนเต็มโดยการตัดออกทุกอย่างต่อไปนี้จุดทศนิยม (ถ้าคุณต้องการที่จะใช้parseInt() เพราะปัญหานี้คุณอาจจะดีกว่าการใช้วิธีการอื่นแทน ) :

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

สตริงว่าง

สตริงที่ว่างเปล่าอาจตอบโต้ได้เล็กน้อย +numแปลงสตริงหรือสตริงว่างที่มีช่องว่างเป็นศูนย์และisNaN()ถือว่าเหมือนกัน:

+''                // 0
+'   '             // 0
isNaN('')          // false
isNaN('   ')       // false

แต่parseInt()ไม่เห็นด้วย:

parseInt('')       // NaN
parseInt('   ')    // NaN

133
หมายเหตุสำคัญมากเกี่ยวกับ parseInt คือมันจะช่วยให้คุณระบุ radix สำหรับการแปลงสตริงเป็น int นี่เป็น gotcha ที่ยิ่งใหญ่เพราะมันพยายามเดา radix ให้กับคุณ ตัวอย่างเช่น: parseInt ("17") ให้ผลลัพธ์เป็น 17 (ฐานสิบ, 10) แต่ parseInt ("08") ให้ผลลัพธ์เป็น 0 (ฐานแปด, 8) ดังนั้นหากคุณไม่ได้ตั้งใจเป็นอย่างอื่นคุณควรใช้ parseInt (หมายเลข 10) โดยระบุ 10 เป็นฐานอย่างชัดเจน
Adam Raney

36
โปรดทราบว่า! isNaN (ไม่ได้กำหนด) จะคืนค่าเท็จ
David Hellsing

111
นี่เป็นเพียงความผิดธรรมดา - มันทำให้เกิด upvotes มากมายได้อย่างไร คุณไม่สามารถใช้isNaN"เพื่อตรวจสอบเพื่อดูว่าตัวแปรไม่ใช่ตัวเลข" หรือไม่ "ไม่ใช่ตัวเลข" ไม่เหมือนกับ "IEEE-794 NaN" ซึ่งเป็นสิ่งที่ใช้isNaNทดสอบ โดยเฉพาะอย่างยิ่งการใช้งานนี้ล้มเหลวเมื่อทดสอบบูลีนและสตริงว่างเปล่าอย่างน้อย ดูdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
EML

46
วิธีที่เร็วที่สุดที่เป็นไปได้ในการตรวจสอบว่าบางสิ่งบางอย่างเป็นตัวเลขคือการตรวจสอบ "เท่ากับตัวเอง": var n = 'a'; if (+n === +n) { // is number }เร็วกว่า ~ 3994% เร็วกว่า isNaN ใน Chrome เวอร์ชันล่าสุด ดูการทดสอบประสิทธิภาพได้ที่นี่: jsperf.com/isnan-vs-typeof/5
Kevin Jurkowski

22
** คำเตือน ** คำตอบนี้ผิด ใช้ความเสี่ยงของคุณเอง ตัวอย่าง:isNaN(1 + false + parseInt("1.do you trust your users?"))
keithpjolley

55

และคุณสามารถไปยัง RegExp-way:

var num = "987238";

if(num.match(/^-{0,1}\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}

40
ในกรณีนี้ RegExp == ไม่ดี
Joel Coehoorn

10
สิ่งนี้ล้มเหลวกับตัวเลขฐานสิบหก (เช่น 0x12) ลอยโดยไม่มีศูนย์นำหน้า (.42 เป็นต้น) และจำนวนลบ
Ori

17
@JoelCoehoorn สนใจที่จะอธิบายอย่างละเอียดว่าทำไม RegExp == ไม่ดีที่นี่หรือไม่ ดูเหมือนว่าจะเป็นกรณีการใช้งานที่ถูกต้องกับฉัน
คอมพิวเตอร์

6
มีหลายวิธีที่ดูเหมือนว่าจะสร้างตัวเลข (ตัวเลขฐานสิบหกในความคิดเห็นอื่นเป็นเพียงตัวอย่างเดียว) และมีตัวเลขจำนวนมากที่อาจถือว่าไม่ถูกต้อง (ล้นประเภทแม่นยำเกินไป ฯลฯ ) นอกจากนี้ regex เป็นทั้งช้าลงและมีความซับซ้อนมากขึ้นกว่าเพียงแค่ใช้ในตัวกลไก
โจเอล Coehoorn

1
ควรตรงกับสัญกรณ์ทางวิทยาศาสตร์ ... 1e10 เป็นต้น
โจเซฟ Merdrignac

51

หากคุณเพียงแค่พยายามตรวจสอบว่าสตริงเป็นจำนวนเต็ม (ไม่มีทศนิยม) regex เป็นวิธีที่ดีที่จะไป วิธีอื่น ๆ เช่นisNaNซับซ้อนเกินไปสำหรับบางสิ่งที่ง่ายมาก

function isNumeric(value) {
    return /^-{0,1}\d+$/.test(value);
}

console.log(isNumeric('abcd'));         // false
console.log(isNumeric('123a'));         // false
console.log(isNumeric('1'));            // true
console.log(isNumeric('1234567890'));   // true
console.log(isNumeric('-23'));          // true
console.log(isNumeric(1234));           // true
console.log(isNumeric('123.4'));        // false
console.log(isNumeric(''));             // false
console.log(isNumeric(undefined));      // false
console.log(isNumeric(null));           // false

หากต้องการอนุญาตให้ใช้จำนวนเต็มบวกเท่านั้นให้ทำดังนี้

function isNumeric(value) {
    return /^\d+$/.test(value);
}

console.log(isNumeric('123'));          // true
console.log(isNumeric('-23'));          // false

11
console.log (IsNumeric ( '- 1'));
yongnan

5
console.log (IsNumeric ( '2e2'));
Gaël Barbin

11
อาจแค่เปลี่ยนชื่อ "isNumeric" เป็น "hasOnlyDigits" ในหลาย ๆ กรณีนั่นเป็นสิ่งที่คุณต้องการอย่างแน่นอน
gus3001

1
นี่คือสิ่งที่ฉันกำลังมองหาเทียบเท่ากับ php ctype_digit
Miguel Pynto

/^-?\d+$/ขวา?
Sukima

36

ถ้าคุณต้องการเพื่อให้แน่ใจว่าสตริงมีเพียงจำนวนจำนวนใด ๆ (จำนวนเต็มหรือจุดลอย) และว่าจำนวนที่คุณไม่สามารถใช้parseInt()/ parseFloat(), Number()หรือ!isNaN()ด้วยตัวเอง โปรดทราบว่า!isNaN()จริง ๆ แล้วจะส่งคืนtrueเมื่อNumber()จะส่งคืนหมายเลขและfalseเมื่อมันจะส่งกลับNaNดังนั้นฉันจะแยกออกจากการสนทนาที่เหลือ

ปัญหาparseFloat()คือมันจะส่งกลับจำนวนถ้าสตริงมีจำนวนใด ๆ แม้ว่าสตริงไม่ได้มีเพียงและจำนวนที่แน่นอน :

parseFloat("2016-12-31")  // returns 2016
parseFloat("1-1") // return 1
parseFloat("1.2.3") // returns 1.2

ปัญหาNumber()คือมันจะส่งกลับตัวเลขในกรณีที่ค่าที่ส่งผ่านไม่ใช่ตัวเลขเลย!

Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0   \t\n\r") // returns 0

ปัญหาของการกลิ้ง regex ของคุณเองก็คือถ้าคุณไม่สร้าง regex ที่แน่นอนสำหรับการจับคู่หมายเลขทศนิยมเนื่องจาก Javascript รับรู้ว่าคุณกำลังจะพลาดกรณีหรือรับรู้กรณีที่คุณไม่ควร และแม้ว่าคุณจะสามารถหมุน regex ของคุณเองทำไม? มีวิธีการติดตั้งในตัวที่ง่ายกว่า

อย่างไรก็ตามปรากฎว่าNumber()(และisNaN()) ทำสิ่งที่ถูกต้องสำหรับทุกกรณีที่parseFloat()ส่งกลับตัวเลขเมื่อไม่ควรและในทางกลับกัน ดังนั้นหากต้องการทราบว่าสตริงเป็นจำนวนจริงหรือเพียงแค่ตัวเลขให้เรียกทั้งสองฟังก์ชั่นแล้วดูว่าพวกมันทั้งคู่คืนค่าเป็นจริงหรือไม่:

function isNumber(str) {
  if (typeof str != "string") return false // we only process strings!
  // could also coerce to string: str = ""+str
  return !isNaN(str) && !isNaN(parseFloat(str))
}

2
สิ่งนี้จะคืนค่าจริงเมื่อสตริงมีช่องว่างนำหน้าหรือต่อท้าย ' 1', '2 'และ' 3 'ทั้งหมดกลับจริง
Rudey

การเพิ่มสิ่งนี้ในคำสั่ง return จะช่วยแก้ปัญหานั้น: &&! / ^ \ s + | \ s + $ / g.test (str)
Ultroman the Tacoman

2
@RuudLenders - คนส่วนใหญ่จะไม่สนใจว่ามีช่องว่างต่อท้ายที่หลุดออกมาเพื่อให้สตริงเป็นจำนวนที่ถูกต้องเพราะมันง่ายที่จะใส่ในช่องว่างพิเศษในอินเตอร์เฟซจำนวนมากโดยไม่ตั้งใจ
เอียน

3
เป็นจริงในกรณีที่สตริงตัวเลขมาจากอินพุตของผู้ใช้ แต่ฉันคิดว่าฉันควรพูดถึงช่องว่างเพราะฉันคิดว่าคนส่วนใหญ่ที่ต้องการisNumberฟังก์ชั่นไม่ได้เกี่ยวข้องกับส่วนต่อประสานผู้ใช้ นอกจากนี้การป้อนตัวเลขที่ดีจะไม่อนุญาตให้เว้นวรรคเริ่มต้นด้วย
Rudey

36

คำตอบที่ได้รับการยอมรับสำหรับคำถามนี้มีข้อบกพร่องเล็กน้อย (ดังที่ถูกเน้นโดยผู้ใช้คนอื่นสองสามคน) นี่เป็นหนึ่งในวิธีที่ง่ายที่สุดและพิสูจน์แล้วว่าใช้งานได้ใน javascript:

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

ด้านล่างนี้เป็นกรณีทดสอบที่ดี:

console.log(isNumeric(12345678912345678912)); // true
console.log(isNumeric('2 '));                 // true
console.log(isNumeric('-32.2 '));             // true
console.log(isNumeric(-32.2));                // true
console.log(isNumeric(undefined));            // false

// the accepted answer fails at these tests:
console.log(isNumeric(''));                   // false
console.log(isNumeric(null));                 // false
console.log(isNumeric([]));                   // false

22

ลองใช้ฟังก์ชั่น isNan :

ฟังก์ชั่น isNaN () กำหนดว่าค่าเป็นตัวเลขที่ผิดกฎหมาย (Not-a-Number) หรือไม่

ฟังก์ชันนี้จะคืนค่าจริงถ้าค่าเท่ากับ NaN มิฉะนั้นจะส่งคืนค่าเท็จ

ฟังก์ชั่นนี้จะแตกต่างจากจำนวนที่เฉพาะเจาะจงNumber.isNaN ()วิธีการ

  ฟังก์ชั่นทั่วโลก isNaN (), แปลงค่าที่ทดสอบเป็นตัวเลขแล้วทดสอบ

Number.isNan () ไม่แปลงค่าเป็น Number และจะไม่ส่งคืนค่าจริงสำหรับค่าใด ๆ ที่ไม่ใช่ประเภท Number ...


2
ตรวจสอบให้แน่ใจว่าคุณเพิ่มการตรวจสอบสำหรับสตริงว่าง isNaN ('') คืนค่าเท็จ แต่คุณอาจต้องการให้คืนค่าจริงในกรณีนี้
Michael Haren

3
isFinite เป็นการตรวจสอบที่ดีกว่า - มันเกี่ยวข้องกับกรณีมุมแปลก ๆ ของ Infinity
JonnyRaa

3
@MichaelHaren ไม่ดีพอ! isNaN()ผลตอบแทนfalseสำหรับการใด ๆสตริงที่มีเพียงตัวอักษรช่องว่างรวมทั้งสิ่งที่ชอบ '\ u00A0'
Michael

1
คำเตือน: ใช้ไม่ได้กับค่า: null, "" (สตริงว่าง) และ false
Jenny O'Reilly

ฉันรู้ว่าคำตอบนี้ได้รับเมื่อ 11 ปีที่แล้วและไม่กี่นาทีก่อนคำตอบที่ได้รับการยอมรับ แต่ชอบหรือไม่คำตอบที่ยอมรับมีการสนทนาเพิ่มเติมรอบ ๆ ดังนั้นคำตอบนี้ไม่ได้เพิ่มอะไรเลยในการตอบคำถาม ฉันขอแนะนำให้ลบมันเพื่อหลีกเลี่ยงการรบกวนผู้อ่านใหม่ ฉันยังคิดว่าคุณจะได้รับตราสัญลักษณ์หากคุณทำเช่นนั้น
Dan Dascalescu

14

คำถามเก่า แต่มีหลายจุดที่ขาดหายไปในคำตอบที่ให้

สัญกรณ์วิทยาศาสตร์.

!isNaN('1e+30')เป็นแต่ในส่วนของกรณีที่เมื่อมีคนถามหาตัวเลขพวกเขาไม่ต้องการให้ตรงกับสิ่งที่ชอบtrue1e+30

ตัวเลขลอยตัวขนาดใหญ่อาจมีพฤติกรรมแปลก ๆ

สังเกต (ใช้ Node.js):

> var s = Array(16 + 1).join('9')
undefined
> s.length
16
> s
'9999999999999999'
> !isNaN(s)
true
> Number(s)
10000000000000000
> String(Number(s)) === s
false
>

ในทางกลับกัน:

> var s = Array(16 + 1).join('1')
undefined
> String(Number(s)) === s
true
> var s = Array(15 + 1).join('9')
undefined
> String(Number(s)) === s
true
>

ดังนั้นหากคาดว่าจะString(Number(s)) === sดีกว่า จำกัด สตริงของคุณไว้ที่ 15 หลัก (หลังจากละเว้นศูนย์นำหน้า)

ความไม่มีที่สิ้นสุด

> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>

ให้ทั้งหมดนั้นตรวจสอบว่าสตริงที่กำหนดเป็นตัวเลขที่น่าพอใจต่อไปนี้ทั้งหมด:

  • ไม่ใช่สัญลักษณ์ทางวิทยาศาสตร์
  • การแปลงที่คาดการณ์ได้เป็นNumberและกลับสู่String
  • จำกัด

ไม่ใช่เรื่องง่าย นี่เป็นเวอร์ชั่นง่าย ๆ :

  function isNonScientificNumberString(o) {
    if (!o || typeof o !== 'string') {
      // Should not be given anything but strings.
      return false;
    }
    return o.length <= 15 && o.indexOf('e+') < 0 && o.indexOf('E+') < 0 && !isNaN(o) && isFinite(o);
  }

อย่างไรก็ตามแม้อันนี้ยังห่างไกลจากความสมบูรณ์ ศูนย์ชั้นนำไม่ได้รับการจัดการที่นี่ แต่พวกเขาจะทดสอบความยาวสกรู


1
"อย่างไรก็ตามในกรณีส่วนใหญ่เมื่อมีคนถามหาตัวเลขพวกเขาไม่ต้องการจับคู่สิ่งต่าง ๆ เช่น 1e + 30" ทำไมคุณถึงพูดแบบนี้ หากมีคนต้องการรู้ว่าสตริงมีตัวเลขหรือไม่ดูเหมือนว่าฉันต้องการรู้ว่ามันมีตัวเลขหรือไม่และ 1e + 30 เป็นตัวเลข แน่นอนถ้าฉันกำลังทดสอบสตริงสำหรับค่าตัวเลขใน JavaScript ฉันต้องการจับคู่นั้น
Dan Jones

9

ฉันทดสอบแล้วและทางออกของ Michael ดีที่สุด โหวตให้กับคำตอบของเขาด้านบน (ค้นหาหน้านี้เพื่อ "ถ้าคุณต้องการให้แน่ใจว่าสตริง" เพื่อหามัน) ในสาระสำคัญคำตอบของเขาคือ:

function isNumeric(num){
  num = "" + num; //coerce num to be a string
  return !isNaN(num) && !isNaN(parseFloat(num));
}

มันใช้งานได้กับทุกกรณีทดสอบซึ่งฉันบันทึกไว้ที่นี่: https://jsfiddle.net/wggehvp9/5/

การแก้ปัญหาอื่น ๆ จำนวนมากล้มเหลวในกรณีขอบเหล่านี้: '', null, "", จริงและ [] ในทางทฤษฎีคุณสามารถใช้มันโดยมีข้อผิดพลาดที่เหมาะสมเช่น:

return !isNaN(num);

หรือ

return (+num === +num);

ด้วยการจัดการพิเศษสำหรับ / \ s /, null, "", จริง, เท็จ, [] (และอื่น ๆ ?)


1
สิ่งนี้ยังคงกลับมาจริงด้วยช่องว่างต่อท้าย / นำหน้า การเพิ่มสิ่งนี้ในคำสั่ง return จะช่วยแก้ปัญหานั้น: &&! / ^ \ s + | \ s + $ / g.test (str)
Ultroman the Tacoman

2
ดังนั้น '123' ควรเป็นเท็จไม่ใช่ตัวเลขในขณะที่ '1234' ควรเป็นตัวเลข ฉันชอบที่มันเป็นอย่างนั้นเพื่อให้ "123" เป็นตัวเลข แต่อาจขึ้นอยู่กับดุลยพินิจของนักพัฒนาหากการเว้นวรรคชั้นนำหรือช่องว่างควรเปลี่ยนค่า
JohnP2

8

คุณสามารถใช้ผลลัพธ์ของNumberเมื่อส่งอาร์กิวเมนต์ไปยัง Constructor

หากอาร์กิวเมนต์ (สตริง) ไม่สามารถแปลงเป็นตัวเลขได้จะส่งคืน NaN ดังนั้นคุณสามารถกำหนดได้ว่าสตริงที่ระบุเป็นตัวเลขที่ถูกต้องหรือไม่

Notes: หมายเหตุเมื่อส่งผ่านสตริงว่างหรือ '\t\t'และ'\n\t'เป็น Number จะส่งคืน 0 การผ่าน true จะส่งคืน 1 และ false ส่งคืน 0

    Number('34.00') // 34
    Number('-34') // -34
    Number('123e5') // 12300000
    Number('123e-5') // 0.00123
    Number('999999999999') // 999999999999
    Number('9999999999999999') // 10000000000000000 (integer accuracy up to 15 digit)
    Number('0xFF') // 255
    Number('Infinity') // Infinity  

    Number('34px') // NaN
    Number('xyz') // NaN
    Number('true') // NaN
    Number('false') // NaN

    // cavets
    Number('    ') // 0
    Number('\t\t') // 0
    Number('\n\t') // 0

คอนสตรัคเป็นเหมือนกับNumber +x
GregRos

ตามบันทึกข้างเก็บไว้ในใจว่า ES6 Number()จับลอยตัวเลขด้วยเช่นNumber.parseFloat()ไม่ได้Number.parseInt()
zurfyx

7

อาจมีคนหนึ่งหรือสองคนที่เจอคำถามนี้ซึ่งต้องการการตรวจสอบที่เข้มงวดกว่าปกติ (เหมือนที่ฉันทำ) ในกรณีนี้สิ่งนี้อาจมีประโยชน์:

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}

ระวัง! นี้จะปฏิเสธสตริงชอบ.1, 40.000, ,080 00.1เป็นเรื่องที่พิถีพิถันมาก - สตริงจะต้องตรงกับ " รูปแบบที่สมบูรณ์แบบที่สุดน้อยที่สุด " ของจำนวนที่การทดสอบนี้จะผ่าน

มันใช้StringและคอนNumberสตรัคเพื่อโยนสตริงกลับไปเป็นตัวเลขและกลับมาอีกครั้งและตรวจสอบว่า "สมบูรณ์แบบน้อยที่สุด" ของโปรแกรมจาวาสคริปต์ (อันที่มันถูกแปลงเป็นคอนNumberสตรัคชันเริ่มต้น) ตรงกับสตริงเดิม


2
ขอบคุณ @JoeRocc ผมจำเป็นต้องมีนี้เกินไป (str === String(Math.round(Number(str))))แต่เพียงสำหรับจำนวนเต็มดังนั้นฉันเพิ่ม:
keithpjolley

โปรดทราบว่า"Infinity", "-Infinity"และ"NaN"ผ่านการทดสอบนี้ อย่างไรก็ตามสามารถแก้ไขได้โดยใช้การNumber.isFiniteทดสอบเพิ่มเติม
GregRos

str === ("" + +str)ตรงนี้เป็นเช่นเดียวกับ มันเป็นพื้นตรวจสอบว่าสตริงเป็นผลมาจากการ stringifying หมายเลข JS เมื่อรู้สิ่งนี้เราสามารถเห็นปัญหาได้ด้วย: การทดสอบผ่าน0.000001แต่ไม่ผ่าน0.0000001ซึ่งก็คือเมื่อ1e-7ผ่านแทน เช่นเดียวกันสำหรับตัวเลขขนาดใหญ่มาก
GregRos

5

parseInt () แต่ระวังว่าฟังก์ชั่นนี้จะแตกต่างกันเล็กน้อยในแง่ที่ว่ามันส่งคืนตัวอย่าง 100 สำหรับ parseInt ("100px")


และ 11 parseInt(09)สำหรับ
djechlin

10
เพราะคุณจำเป็นต้องใช้paraseInt(09, 10)
Gavin

1
ในฐานะของ ECMAScript 5ซึ่งมีการสนับสนุนเบราว์เซอร์ที่กว้าง (IE≥9) คุณไม่จำเป็นต้องมี, 10ข้อโต้แย้งอีกต่อไป parseInt('09')ตอนนี้เท่ากับ 9
Rory O'Kane

4

อ้างถึง:

isNaN (NUM) // คืนค่าจริงถ้าตัวแปรไม่มีตัวเลขที่ถูกต้อง

ไม่เป็นความจริงทั้งหมดหากคุณต้องการตรวจสอบช่องว่างนำหน้า / ต่อท้ายตัวอย่างเช่นเมื่อต้องการจำนวนตัวเลขที่แน่นอนและคุณต้องได้รับพูดว่า '1111' และไม่ใช่ '111' หรือ '111' สำหรับ PIN อินพุต

ดีกว่าที่จะใช้:

var num = /^\d+$/.test(num)

ค่า'-1', '0.1'และ'1e10'ผลตอบแทนทั้งหมดเป็นเท็จ นอกจากนี้ค่าที่มากกว่าค่าบวกอนันต์หรือเล็กกว่าค่าลบอนันต์จะคืนค่าเป็นจริงในขณะที่ค่าเหล่านั้นอาจกลับเท็จ
Rudey

4

เหตุใดการดำเนินการของ jQuery จึงไม่ดีพอ

function isNumeric(a) {
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0;
};

Michael แนะนำสิ่งนี้ (แม้ว่าฉันขโมย "user1691651 - John" เวอร์ชันที่แก้ไขของที่นี่):

function isNumeric(num){
    num = "" + num; //coerce num to be a string
    return !isNaN(num) && !isNaN(parseFloat(num));
}

ต่อไปนี้เป็นโซลูชันที่มีประสิทธิภาพไม่ดีที่สุด แต่ให้ผลลัพธ์ที่มั่นคง มันเป็นสิ่งที่ตรงกันข้ามกับการใช้ jQuery 1.12.4 และคำตอบของไมเคิลโดยมีการตรวจสอบพิเศษสำหรับช่องว่างนำหน้า / ต่อท้าย (เนื่องจากเวอร์ชันของไมเคิลส่งกลับค่าจริงสำหรับตัวเลขด้วยช่องว่างนำหน้า / ท้าย):

function isNumeric(a) {
    var str = a + "";
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0 &&
           !/^\s+|\s+$/g.test(str) &&
           !isNaN(str) && !isNaN(parseFloat(str));
};

รุ่นหลังมีตัวแปรใหม่สองตัว ใครคนใดคนหนึ่งสามารถทำได้โดยทำ:

function isNumeric(a) {
    if ($.isArray(a)) return false;
    var b = a && a.toString();
    a = a + "";
    return b - parseFloat(b) + 1 >= 0 &&
            !/^\s+|\s+$/g.test(a) &&
            !isNaN(a) && !isNaN(parseFloat(a));
};

ฉันยังไม่ได้ทดสอบสิ่งเหล่านี้มากนักโดยวิธีอื่นนอกเหนือจากการทดสอบการใช้งานสองสามกรณีด้วยตนเองฉันจะไปกระทบกับสถานการณ์ปัจจุบันของฉันซึ่งเป็นสิ่งมาตรฐานทั้งหมด นี่คือสถานการณ์ "ยืนอยู่บนไหล่ของยักษ์"


4

มันไม่ถูกต้องสำหรับ TypeScript เป็น:

declare function isNaN(number: number): boolean;

สำหรับ TypeScript คุณสามารถใช้:

/^\d+$/.test(key)


3

ฉันใช้สิ่งนี้ที่ฉันทำ ...

มันใช้งานได้แล้ว:

function checkNumber(value) {
    if ( value % 1 == 0 )
    return true;
    else
    return false;
}

หากคุณพบปัญหาใด ๆ กับมันโปรดบอกฉันที


12
สิ่งนี้ให้ผลลัพธ์ที่ไม่ถูกต้องสำหรับสตริงว่างอาเรย์ว่างเปล่าเท็จและ null
Ori

2
มันควรจะเป็นสามเท่าหรือไม่?
toasted_flakes

1
ในใบสมัครของฉันเราอนุญาตให้ใช้ AZ AZ และอักขระ 0-9 เท่านั้น ฉันพบการทำงานข้างต้นเว้นแต่สตริงเริ่มต้นด้วย 0xnn แล้วมันจะคืนค่าเป็นตัวเลขเมื่อไม่ควรมีฉันโพสต์ในความคิดเห็นด้านล่างเพื่อให้การจัดรูปแบบไม่เป็นอันตราย
rwheadon

6
คุณสามารถทำได้ 'คืนค่า% 1 === 0'
Brian Schermerhorn

เพิ่งทำreturn !isNaN(parseInt(value, 10));
DarkNeuron

3

หากใครที่เคยทำสิ่งนี้มาไกลฉันใช้เวลาในการแฮ็คข้อมูลนี้เพื่อพยายามแก้ไข moment.js ( https://github.com/moment/moment ) นี่คือสิ่งที่ฉันเอาออกไปจากมัน:

function isNumeric(val) {
    var _val = +val;
    return (val !== val + 1) //infinity check
        && (_val === +val) //Cute coercion check
        && (typeof val !== 'object') //Array/object check
}

จัดการกับกรณีต่อไปนี้:

ความจริง! :

isNumeric("1"))
isNumeric(1e10))
isNumeric(1E10))
isNumeric(+"6e4"))
isNumeric("1.2222"))
isNumeric("-1.2222"))
isNumeric("-1.222200000000000000"))
isNumeric("1.222200000000000000"))
isNumeric(1))
isNumeric(0))
isNumeric(-0))
isNumeric(1010010293029))
isNumeric(1.100393830000))
isNumeric(Math.LN2))
isNumeric(Math.PI))
isNumeric(5e10))

เท็จ! :

isNumeric(NaN))
isNumeric(Infinity))
isNumeric(-Infinity))
isNumeric())
isNumeric(undefined))
isNumeric('[1,2,3]'))
isNumeric({a:1,b:2}))
isNumeric(null))
isNumeric([1]))
isNumeric(new Date()))

แดกดันสิ่งที่ฉันกำลังดิ้นรนกับคนส่วนใหญ่:

isNumeric(new Number(1)) => false

ข้อเสนอแนะใด ๆ ยินดีต้อนรับ :]


2
สิ่งที่เกี่ยวกับisNumeric(' ')และisNumeric('')?
Alex Cory

ฉันจะเพิ่ม&& (val.replace(/\s/g,'') !== '') //Empty && (val.slice(-1) !== '.') //Decimal without Numberเพื่อที่อยู่ปัญหาดังกล่าวข้างต้นและหนึ่งฉันมีตัวเอง
frankenapps


3
function isNumberCandidate(s) {
  const str = (''+ s).trim();
  if (str.length === 0) return false;
  return !isNaN(+str);
}

console.log(isNumberCandidate('1'));       // true
console.log(isNumberCandidate('a'));       // false
console.log(isNumberCandidate('000'));     // true
console.log(isNumberCandidate('1a'));      // false 
console.log(isNumberCandidate('1e'));      // false
console.log(isNumberCandidate('1e-1'));    // true
console.log(isNumberCandidate('123.3'));   // true
console.log(isNumberCandidate(''));        // false
console.log(isNumberCandidate(' '));       // false
console.log(isNumberCandidate(1));         // true
console.log(isNumberCandidate(0));         // true
console.log(isNumberCandidate(NaN));       // false
console.log(isNumberCandidate(undefined)); // false
console.log(isNumberCandidate(null));      // false
console.log(isNumberCandidate(-1));        // true
console.log(isNumberCandidate('-1'));      // true
console.log(isNumberCandidate('-1.2'));    // true
console.log(isNumberCandidate(0.0000001)); // true
console.log(isNumberCandidate('0.0000001')); // true
console.log(isNumberCandidate(Infinity));    // true
console.log(isNumberCandidate(-Infinity));    // true

console.log(isNumberCandidate('Infinity'));  // true

if (isNumberCandidate(s)) {
  // use +s as a number
  +s ...
}

ขอบคุณคำตอบยอดเยี่ยม!
M.Abulsoud

3

2019: รวมถึงตัวอย่าง ES3, ES6 และ TypeScript

บางทีนี่อาจได้รับการปรับปรุงหลายครั้งเกินไป แต่ฉันก็ต่อสู้กับมันในวันนี้ด้วยและต้องการโพสต์คำตอบของฉันเพราะฉันไม่เห็นคำตอบอื่นใดที่เรียบง่ายหรือทั่วถึง:

ES3

var isNumeric = function(num){
    return (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);  
}

ES6

const isNumeric = (num) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);

สิ่งที่พิมพ์ด้วยพิมพ์ดีด

const isNumeric = (num: any) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num as number);

ดูเหมือนจะค่อนข้างง่ายและครอบคลุมฐานทั้งหมดที่ฉันเห็นในโพสต์อื่น ๆ และคิดขึ้นเอง:

// Positive Cases
console.log(0, isNumeric(0) === true);
console.log(1, isNumeric(1) === true);
console.log(1234567890, isNumeric(1234567890) === true);
console.log('1234567890', isNumeric('1234567890') === true);
console.log('0', isNumeric('0') === true);
console.log('1', isNumeric('1') === true);
console.log('1.1', isNumeric('1.1') === true);
console.log('-1', isNumeric('-1') === true);
console.log('-1.2354', isNumeric('-1.2354') === true);
console.log('-1234567890', isNumeric('-1234567890') === true);
console.log(-1, isNumeric(-1) === true);
console.log(-32.1, isNumeric(-32.1) === true);
console.log('0x1', isNumeric('0x1') === true);  // Valid number in hex
// Negative Cases
console.log(true, isNumeric(true) === false);
console.log(false, isNumeric(false) === false);
console.log('1..1', isNumeric('1..1') === false);
console.log('1,1', isNumeric('1,1') === false);
console.log('-32.1.12', isNumeric('-32.1.12') === false);
console.log('[blank]', isNumeric('') === false);
console.log('[spaces]', isNumeric('   ') === false);
console.log('null', isNumeric(null) === false);
console.log('undefined', isNumeric(undefined) === false);
console.log([], isNumeric([]) === false);
console.log('NaN', isNumeric(NaN) === false);

นอกจากนี้คุณยังสามารถลองisNumericใช้ฟังก์ชั่นของคุณเองและผ่านไปในกรณีการใช้งานเหล่านี้และสแกนหา "ความจริง" สำหรับพวกเขาทั้งหมด

หรือเพื่อดูค่าที่แต่ละค่าส่งคืน:

ผลลัพธ์ของการทดสอบแต่ละครั้งกับ <code> คือตัวเลข () </code>


3

2019: การตรวจสอบความถูกต้องเชิงตัวเลขและการปฏิบัติที่รัดกุม

บ่อยครั้งที่ 'หมายเลขที่ถูกต้อง' หมายถึงหมายเลข Javascript ที่ไม่รวม NaN และ Infinity เช่น 'จำนวน จำกัด '

ในการตรวจสอบความถูกต้องเชิงตัวเลขของค่า (จากแหล่งภายนอกเช่น) คุณสามารถกำหนดในสไตล์ ESlint Airbnb:

/**
 * Returns true if 'candidate' is a finite number or a string referring (not just 'including') a finite number
 * To keep in mind:
 *   Number(true) = 1
 *   Number('') = 0
 *   Number("   10  ") = 10
 *   !isNaN(true) = true
 *   parseFloat('10 a') = 10
 *
 * @param {?} candidate
 * @return {boolean}
 */
function isReferringFiniteNumber(candidate) {
  if (typeof (candidate) === 'number') return Number.isFinite(candidate);
  if (typeof (candidate) === 'string') {
    return (candidate.trim() !== '') && Number.isFinite(Number(candidate));
  }
  return false;
}

และใช้วิธีนี้:

if (isReferringFiniteNumber(theirValue)) {
  myCheckedValue = Number(theirValue);
} else {
  console.warn('The provided value doesn\'t refer to a finite number');
}

2

PFB โซลูชั่นการทำงาน:

 function(check){ 
    check = check + "";
    var isNumber =   check.trim().length>0? !isNaN(check):false;
    return isNumber;
    }

2

ช่วยตัวเองด้วยอาการปวดหัวจากการพยายามหาวิธีแก้ปัญหา "ในตัว"

ไม่มีคำตอบที่ดีและคำตอบที่ upvoted อย่างมหาศาลในชุดข้อความนี้ไม่ถูกต้อง

npm install is-number

ในจาวาสคริปต์มันไม่ได้ตรงไปตรงมาเสมออย่างที่ควรจะตรวจสอบอย่างน่าเชื่อถือว่าค่าเป็นตัวเลขหรือไม่ เป็นเรื่องปกติที่ devs จะใช้ +, - หรือ Number () เพื่อแปลงค่าสตริงเป็นตัวเลข (ตัวอย่างเช่นเมื่อค่าถูกส่งคืนจากอินพุตของผู้ใช้การจับคู่ regex ตัวแยกวิเคราะห์ ฯลฯ ) แต่มีกรณีขอบที่ไม่ได้ใช้งานง่ายมากมายที่ให้ผลลัพธ์ที่ไม่คาดคิด:

console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+'   '); //=> 0
console.log(typeof NaN); //=> 'number'

1

ฉันเพิ่งเขียนบทความเกี่ยวกับวิธีการตรวจสอบให้แน่ใจว่าตัวแปรเป็นจำนวนที่ถูกต้อง: https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.mdบทความอธิบายถึงวิธีการตรวจสอบจุดลอยตัวหรือจำนวนเต็ม สำคัญ ( +xvs ~~x)

บทความสันนิษฐานว่าตัวแปรคือ a stringหรือ a numberเริ่มต้นด้วยและtrimพร้อมใช้งาน / polyfilled มันคงไม่ยากที่จะขยายออกไปรองรับประเภทอื่น ๆ เช่นกัน นี่คือเนื้อของมัน:

// Check for a valid float
if (x == null
    || ("" + x).trim() === ""
    || isNaN(+x)) {
    return false;  // not a float
}

// Check for a valid integer
if (x == null
    || ("" + x).trim() === ""
    || ~~x !== +x) {
    return false;  // not an integer
}

1

ความพยายามของฉันในความสับสนเล็กน้อยบางทีอาจไม่ใช่ทางออกที่ดีที่สุด

function isInt(a){
    return a === ""+~~a
}


console.log(isInt('abcd'));         // false
console.log(isInt('123a'));         // false
console.log(isInt('1'));            // true
console.log(isInt('0'));            // true
console.log(isInt('-0'));           // false
console.log(isInt('01'));           // false
console.log(isInt('10'));           // true
console.log(isInt('-1234567890'));  // true
console.log(isInt(1234));           // false
console.log(isInt('123.4'));        // false
console.log(isInt(''));             // false

// other types then string returns false
console.log(isInt(5));              // false
console.log(isInt(undefined));      // false
console.log(isInt(null));           // false
console.log(isInt('0x1'));          // false
console.log(isInt(Infinity));       // false

มันไม่ได้แย่เกินไปสองแย่มันใช้ไม่ได้กับสัญกรณ์ที่ไม่ใช่ทศนิยมเช่น (1) สัญกรณ์ทางวิทยาศาสตร์และ (2) not-base-10 สัญกรณ์เช่น octal ( 042) และเลขฐานสิบหก ( 0x45f)
Domi

นี่ไม่ได้ตอบคำถามของการหาค่าตัวเลขมันแค่หาค่า int
Jeremy

0

ในใบสมัครของฉันเราอนุญาตให้ใช้ AZ AZ และอักขระ 0-9 เท่านั้น ฉันพบคำตอบข้างต้นโดยใช้ " string % 1 === 0" ทำงานนอกเสียจากว่าสตริงเริ่มต้นด้วย 0xnn (เช่น 0x10) แล้วมันจะคืนค่าเป็นตัวเลขเมื่อเราไม่ต้องการ กับดักง่าย ๆ ดังต่อไปนี้ในการตรวจสอบตัวเลขของฉันดูเหมือนจะหลอกลวงในกรณีเฉพาะของเรา

function isStringNumeric(str_input){   
    //concat a temporary 1 during the modulus to keep a beginning hex switch combination from messing us up   
    //very simple and as long as special characters (non a-z A-Z 0-9) are trapped it is fine   
    return '1'.concat(str_input) % 1 === 0;}

คำเตือน : นี่อาจเป็นการใช้ประโยชน์จากข้อผิดพลาดที่ยาวนานใน Javascript และ Actionscript [หมายเลข ("1" + the_string)% 1 === 0)] ฉันไม่สามารถพูดได้ แต่เป็นสิ่งที่เราต้องการ


เหตุใดจึงเป็นข้อบกพร่องใน JavaScript
Bergi

ฉันไม่เห็นพฤติกรรมเดียวกันกับโซลูชันที่คล้ายกันใน perl หรือ C และเนื่องจากฉันไม่ใช่นักพัฒนาภาษาการเขียนโปรแกรมสำหรับ javascript หรือ actionscript ฉันไม่ทราบว่าพฤติกรรมที่ฉันกำลังประสบนั้นตั้งใจจริงหรือไม่
rwheadon

จาวาสคริปต์นั้นค่อนข้างเลอะเทอะเล็กน้อยเกี่ยวกับการคัดเลือกนักแสดงโดยปริยาย แต่เมื่อคุณรู้ว่าคุณสามารถเข้าใจวิธีการทำงานได้อย่างง่ายดาย คุณกำลังส่งสตริงไปยังตัวเลข (โดยการเรียกใช้% 1การดำเนินการเชิงตัวเลขกับพวกเขา) และนั่นจะตีความสตริงเป็นเลขฐานสิบหกหรือลอยตัวอักษร
Bergi

0

ทางออกของฉัน:

// returns true for positive ints; 
// no scientific notation, hexadecimals or floating point dots

var isPositiveInt = function(str) { 
   var result = true, chr;
   for (var i = 0, n = str.length; i < n; i++) {
       chr = str.charAt(i);
       if ((chr < "0" || chr > "9") && chr != ",") { //not digit or thousands separator
         result = false;
         break;
       };
       if (i == 0 && (chr == "0" || chr == ",")) {  //should not start with 0 or ,
         result = false;
         break;
       };
   };
   return result;
 };

คุณสามารถเพิ่มเงื่อนไขเพิ่มเติมภายในลูปเพื่อให้เหมาะกับความต้องการของคุณ


0

คุณสามารถใช้ประโยชน์จากประเภทเช่นเดียวกับflow librar y เพื่อรับการตรวจสอบเวลาแบบคงที่และรวบรวม แน่นอนว่าไม่มีประโยชน์อย่างยิ่งสำหรับการป้อนข้อมูลของผู้ใช้

// @flow

function acceptsNumber(value: number) {
  // ...
}

acceptsNumber(42);       // Works!
acceptsNumber(3.14);     // Works!
acceptsNumber(NaN);      // Works!
acceptsNumber(Infinity); // Works!
acceptsNumber("foo");    // Error!

0

นี่คือหนึ่งซับเพื่อตรวจสอบว่าsNumเป็นค่าตัวเลขที่ถูกต้อง; มันได้รับการทดสอบสำหรับอินพุตที่หลากหลาย:

!isNaN(+s.replace(/\s|\$/g, ''));  // returns True if numeric value

0

เพียงใช้isNaN()นี่จะแปลงสตริงเป็นตัวเลขและหากได้รับตัวเลขที่ถูกต้องจะส่งคืนfalse...

isNaN("Alireza"); //return true
isNaN("123"); //return false

0

ฉันใช้สิ่งต่อไปนี้:

const isNumber = s => !isNaN(+s)

การทำงานค่อนข้างดีเป็นหลายกรณี แต่ล้มเหลวกรณีเช่น1..1, 1,1, -32.1.12และที่สำคัญล้มเหลวและundefined NaNหากคุณผ่านundefinedหรือNaNว่ามันจะให้คุณบวกเท็จบอกว่ามันเป็นจำนวน
Jeremy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.