(Tích hợp) theo cách JavaScript để kiểm tra xem một chuỗi có phải là số hợp lệ không


1190

Tôi hy vọng có một cái gì đó trong cùng một không gian khái niệm như IsNumeric()hàm VB6 cũ ?


3
Xem câu hỏi liên quan này , mà tôi đã hỏi một thời gian trước đây.
Michael Haren

38
Nếu bạn đi đến câu hỏi này, hãy cố gắng bỏ qua tất cả các câu trả lời RegEx. Đó không phải là cách để làm điều đó.
Joel Coehoorn

14
Trừ khi ai đó muốn làm chính xác điều đó: Để kiểm tra xem một chuỗi đã cho có định dạng của một dòng chữ số hợp lệ hay không. Tại sao nó phải sai sau đó?
SasQ

17
Câu trả lời được chọn là không chính xác !!! Xem ý kiến của mình, nhưng về cơ bản nó không thành công với ví dụ như isNaN(""), isNaN(" "), isNaN(false), vv Nó lợi nhuận falsecho các, ngụ ý rằng họ là những con số.
Andrew

1
Vì vậy, câu trả lời được chọn là không chính xác, regrec cũng không phải là cách để làm điều đó. Cái nào đúng?
vir chúng tôi

Câu trả lời:


2322

Để kiểm tra xem một biến (bao gồm một chuỗi) có phải là số không, hãy kiểm tra xem đó có phải là số không:

Điều này hoạt động bất kể nội dung biến là một chuỗi hoặc số.

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

Ví dụ

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

Tất nhiên, bạn có thể phủ nhận điều này nếu bạn cần. Ví dụ: để thực hiện IsNumericví dụ bạn đã đưa ra:

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

Để chuyển đổi một chuỗi chứa một số thành một số:

Chỉ hoạt động nếu chuỗi chỉ chứa các ký tự số, nếu không nó sẽ trả về NaN.

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

Ví dụ

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

Để chuyển đổi một chuỗi lỏng lẻo thành một số

Hữu ích cho việc chuyển đổi '12px' thành 12, ví dụ:

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

Ví dụ

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. 

Phao

Hãy nhớ rằng, không giống như +num, parseInt(như tên cho thấy) sẽ chuyển đổi một số float thành một số nguyên bằng cách cắt bỏ mọi thứ theo dấu thập phân (nếu bạn muốn sử dụng parseInt() hành vi này, có lẽ bạn nên sử dụng phương pháp khác tốt hơn ) :

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

Chuỗi rỗng

Chuỗi rỗng có thể là một chút phản trực giác. +numchuyển đổi các chuỗi rỗng hoặc chuỗi có khoảng trắng thành 0 và isNaN()giả sử giống nhau:

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

Nhưng parseInt()không đồng ý:

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

133
Một lưu ý rất quan trọng về parseInt là nó sẽ cho phép bạn chỉ định một cơ số để chuyển đổi chuỗi thành int. Đây là một vấn đề lớn vì nó cố gắng đoán một cơ số cho bạn nếu bạn không cung cấp nó. Vì vậy, ví dụ: parseInt ("17") cho kết quả 17 (thập phân, 10), nhưng parseInt ("08") cho kết quả là 0 (bát phân, 8). Vì vậy, trừ khi bạn có ý định khác, cách an toàn nhất là sử dụng parseInt (số, 10), chỉ định 10 là cơ số rõ ràng.
Adam Raney

36
Lưu ý rằng! IsNaN (không xác định) trả về false.
David Hellsing

111
Điều này hoàn toàn sai - làm thế nào mà nó nhận được nhiều sự ủng hộ như vậy? Bạn không thể sử dụng isNaN"Để kiểm tra xem biến không phải là số". "không phải là số" không giống với "IEEE-794 NaN", đây là những gì isNaNkiểm tra. Cụ thể, việc sử dụng này thất bại khi kiểm tra booleans và chuỗi trống, ít nhất. Xem developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/iêu .
EML

46
Cách nhanh nhất có thể để kiểm tra xem có thứ gì đó là số hay không là kiểm tra "bằng chính mình": var n = 'a'; if (+n === +n) { // is number }Nó nhanh hơn ~ 3994% so với isNaN trong phiên bản Chrome mới nhất. Xem bài kiểm tra hiệu suất tại đây: jsperf.com/isnan-vs-typeof/5
Kevin Jurkowski

22
** Cảnh báo ** Câu trả lời này là sai. Sử dụng có nguy cơ của riêng bạn. Ví dụ:isNaN(1 + false + parseInt("1.do you trust your users?"))
keithpjcar

55

Và bạn có thể đi theo con đường RegExp:

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
Trong trường hợp này, RegExp == bad
Joel Coehoorn

10
Điều này không thành công trên các số thập lục phân (ví dụ 0x12), trôi nổi mà không có số 0 đứng đầu (ví dụ: .42) và số âm.
Ori

17
@JoelCoehoorn Chăm sóc để giải thích tại sao RegExp == xấu ở đây? Có vẻ là một trường hợp sử dụng hợp lệ với tôi.
máy tính

6
Có nhiều cách hơn là dường như xây dựng một số (số hex trong một nhận xét khác chỉ là một ví dụ) và có nhiều số có thể không được coi là hợp lệ (tràn loại, quá chính xác, v.v.). Ngoài ra, regex vừa chậm lại vừa phức tạp hơn so với việc chỉ sử dụng các cơ chế tích hợp sẵn
Joel Coehoorn

1
cũng nên phù hợp với ký hiệu khoa học ... 1e10, v.v.
Joseph Merdrignac

51

Nếu bạn chỉ đang cố kiểm tra xem một chuỗi có phải là một số nguyên không (không có số thập phân), regex là một cách tốt để đi. Các phương pháp khác như isNaNquá phức tạp cho một cái gì đó quá đơn giản.

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

Để chỉ cho phép số nguyên dương sử dụng điều này:

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

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

11
console.log (isNumeric ('- 1'));
Nam bộ

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

11
Có lẽ chỉ cần đổi tên "isNumeric" thành "hasOnlyDigits". trong nhiều trường hợp, đó chính xác là kiểm tra mà bạn đang tìm kiếm.
gus3001

1
Đây là những gì tôi đang tìm kiếm, tương đương với php ctype_digit
Miguel Pynto

/^-?\d+$/đúng?
Sukima

36

Nếu bạn thực sự muốn chắc chắn rằng một chuỗi chỉ chứa một số, bất kỳ số lượng (số nguyên hoặc dấu chấm động), và chính xác một số, bạn không thể sử dụng parseInt()/ parseFloat(), Number()hoặc !isNaN()tự. Lưu ý rằng !isNaN()thực sự trở lại truekhi Number()sẽ trả về một số và falsekhi nào nó sẽ trở lại NaN, vì vậy tôi sẽ loại trừ nó khỏi phần còn lại của cuộc thảo luận.

Vấn đề với parseFloat()là nó sẽ trả về một số nếu chuỗi chứa bất kỳ số nào, ngay cả khi chuỗi không chỉ chứa và chính xác một số:

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

Vấn đề với Number()là nó sẽ trả về một số trong trường hợp giá trị được chuyển hoàn toàn không phải là một số!

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

Vấn đề với việc cuộn regex của riêng bạn là trừ khi bạn tạo regex chính xác để khớp với số dấu phẩy động khi Javascript nhận ra bạn sẽ bỏ lỡ các trường hợp hoặc nhận ra các trường hợp bạn không nên. Và thậm chí nếu bạn có thể cuộn regex của riêng bạn, tại sao? Có những cách đơn giản hơn để làm điều đó.

Tuy nhiên, nó chỉ ra rằng Number()(và isNaN()) thực hiện đúng cho mọi trường hợp parseFloat()trả về một số khi không nên và ngược lại. Vì vậy, để tìm hiểu xem một chuỗi có thực sự chính xác và chỉ một số hay không, hãy gọi cả hai hàm và xem cả hai có trả về true không:

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
Điều này trả về true khi chuỗi có khoảng trắng ở đầu hoặc cuối. ' 1', '2 '' 3 'tất cả trở về đúng.
Rudey

Thêm một cái gì đó như thế này vào câu lệnh return sẽ giải quyết rằng: &&! / ^ \ S + | \ s + $ / g.test (str)
Ultroman the Tacoman

2
@RuudLender - hầu hết mọi người sẽ không quan tâm nếu có các khoảng trống bị tắt để biến chuỗi thành một số hợp lệ, bởi vì nó dễ dàng vô tình đưa vào các khoảng trắng thừa trong nhiều giao diện.
Ian

3
Điều đó đúng trong trường hợp chuỗi số đến từ đầu vào của người dùng. Nhưng tôi nghĩ dù sao tôi cũng nên đề cập đến không gian, bởi vì tôi nghĩ rằng hầu hết những người cần một isNumberchức năng không làm việc với giao diện người dùng. Ngoài ra, một đầu vào số tốt sẽ không cho phép không gian bắt đầu.
Rudey

36

Câu trả lời được chấp nhận cho câu hỏi này có khá nhiều sai sót (như được nhấn mạnh bởi một vài người dùng khác). Đây là một trong những cách dễ nhất và đã được chứng minh để tiếp cận nó trong javascript:

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

Dưới đây là một số trường hợp thử nghiệm tốt:

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

Hãy thử chức năng isNan :

Hàm isNaN () xác định xem một giá trị có phải là số bất hợp pháp không (Không phải là số).

Hàm này trả về true nếu giá trị tương đương với NaN. Nếu không, nó trả về false.

Hàm này khác với phương thức Number.isNaN () cụ thể .

  Hàm isNaN () toàn cầu, chuyển đổi giá trị được kiểm tra thành Số, sau đó kiểm tra nó.

Number.isNan () không chuyển đổi các giá trị thành Số và sẽ không trả về true cho bất kỳ giá trị nào không thuộc loại Số ...


2
Hãy chắc chắn rằng bạn thêm một kiểm tra cho chuỗi trống. isNaN ('') trả về false nhưng có lẽ bạn muốn nó trả về true trong trường hợp này.
Michael Haren

3
isFinite là một kiểm tra tốt hơn - nó liên quan đến trường hợp góc khuất của Infinity
JonnyRaa

3
@MichaelHaren Không đủ tốt! isNaN()trả về falsecho MỌI chuỗi chỉ chứa các ký tự khoảng trắng, bao gồm cả những thứ như '\ u00A0'.
Michael

1
CẢNH BÁO: Không hoạt động cho các giá trị: null, "" (chuỗi trống) và sai.
Jenny O'Reilly

Tôi nhận ra câu trả lời này đã được đưa ra 11 năm trước và một vài phút trước khi câu trả lời được chấp nhận, nhưng dù muốn hay không, câu trả lời được chấp nhận có CÁCH nhiều cuộc trò chuyện xung quanh nó, vì vậy câu trả lời này không thực sự thêm bất cứ điều gì để trả lời câu hỏi. Tôi vui lòng đề nghị xóa nó, để tránh làm mất tập trung độc giả mới. Tôi cũng nghĩ rằng bạn sẽ nhận được huy hiệu Kỷ luật nếu bạn làm điều đó.
Dan Dascalescu

14

Câu hỏi cũ, nhưng có một vài điểm còn thiếu trong các câu trả lời đã cho.

Ký hiệu khoa học.

!isNaN('1e+30')true, tuy nhiên trong hầu hết các trường hợp khi mọi người yêu cầu số, họ không muốn khớp với những thứ như 1e+30.

Số lượng lớn có thể hành xử kỳ lạ

Quan sát (sử dụng 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
>

Mặt khác:

> 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
>

Vì vậy, nếu ai đó mong đợi String(Number(s)) === s, thì tốt nhất nên giới hạn chuỗi của bạn tối đa 15 chữ số (sau khi bỏ qua các số 0 đứng đầu).

vô cực

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

Với tất cả điều đó, kiểm tra xem chuỗi đã cho có phải là một số thỏa mãn tất cả những điều sau đây không:

  • ký hiệu không khoa học
  • chuyển đổi dự đoán sang Numbervà quay lạiString
  • có hạn

không phải là một nhiệm vụ dễ dàng. Đây là một phiên bản đơn giản:

  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);
  }

Tuy nhiên, ngay cả điều này là xa hoàn thành. Các số 0 đứng đầu không được xử lý ở đây, nhưng chúng thực hiện kiểm tra độ dài.


1
"Tuy nhiên, trong hầu hết các trường hợp khi mọi người yêu cầu số, họ không muốn khớp những thứ như 1e + 30" Tại sao bạn lại nói điều này? Nếu ai đó muốn biết nếu một chuỗi chứa một số, thì đối với tôi, họ muốn biết nếu nó chứa một số và 1e + 30 là một số. Chắc chắn nếu tôi đang kiểm tra một chuỗi cho một giá trị số trong JavaScript, tôi sẽ muốn nó khớp với.
Dan Jones

9

Tôi đã thử nghiệm và giải pháp của Michael là tốt nhất. Bình chọn cho câu trả lời của anh ấy ở trên (tìm kiếm trang này cho "Nếu bạn thực sự muốn chắc chắn rằng một chuỗi" để tìm thấy nó). Về bản chất, câu trả lời của anh ấy là thế này:

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

Nó hoạt động cho mọi trường hợp thử nghiệm, mà tôi đã ghi lại ở đây: https://jsfiddle.net/wggehvp9/5/

Nhiều giải pháp khác không thành công cho các trường hợp cạnh này: '', null, "", true và []. Về lý thuyết, bạn có thể sử dụng chúng, với việc xử lý lỗi thích hợp, ví dụ:

return !isNaN(num);

hoặc là

return (+num === +num);

với xử lý đặc biệt cho / \ s /, null, "", đúng, sai, [] (và những người khác?)


1
Điều này vẫn trả về đúng với dấu cách / dấu cách hàng đầu. Thêm một cái gì đó như thế này vào câu lệnh return sẽ giải quyết rằng: &&! / ^ \ S + | \ s + $ / g.test (str)
Ultroman the Tacoman

2
Vậy '123' có nên sai, không phải là số, trong khi '1234' nên là số? Tôi thích nó như thế nào, vì vậy "123" là một con số, nhưng điều đó có thể tùy theo ý của nhà phát triển nếu các không gian hàng đầu hoặc dấu sẽ thay đổi giá trị.
JohnP2

8

Bạn có thể sử dụng kết quả của Số khi chuyển một đối số cho hàm tạo của nó.

Nếu đối số (một chuỗi) không thể được chuyển đổi thành một số, nó sẽ trả về NaN, do đó bạn có thể xác định xem chuỗi được cung cấp có phải là số hợp lệ hay không.

Lưu ý: Lưu ý khi truyền chuỗi rỗng hoặc '\t\t''\n\t'Số sẽ trả về 0; Vượt qua đúng sẽ trả về 1 và trả về sai 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

Các Numberconstructor hoàn toàn giống như +x.
GregRos

Lưu ý phụ, hãy nhớ rằng ES6 cũng Number()xử lý số float, giống như Number.parseFloat()khôngNumber.parseInt()
zurfyx

7

Có lẽ có một hoặc hai người bắt gặp câu hỏi này, người cần kiểm tra chặt chẽ hơn bình thường (như tôi đã làm). Trong trường hợp đó, điều này có thể hữu ích:

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

Coi chừng! Điều này sẽ loại bỏ chuỗi như .1, 40.000, 080, 00.1. Nó rất kén chọn - chuỗi phải khớp với " dạng hoàn hảo tối thiểu nhất " của số để bài kiểm tra này vượt qua.

Nó sử dụng hàm tạo StringNumberđể tạo chuỗi thành một số và quay lại và do đó kiểm tra xem "dạng tối thiểu hoàn hảo" của công cụ JavaScript (dạng được chuyển đổi với hàm tạo ban đầu Number) có khớp với chuỗi gốc không.


2
Cảm ơn @JoeRocc. Tôi cũng cần điều này, nhưng chỉ cho số nguyên, vì vậy tôi đã thêm : (str === String(Math.round(Number(str)))).
keithpjcar

Hãy nhận biết rằng "Infinity", "-Infinity""NaN"vượt qua bài kiểm tra này. Tuy nhiên, điều này có thể được khắc phục bằng cách sử dụng một Number.isFinitebài kiểm tra bổ sung .
GregRos

Điều này hoàn toàn giống như str === ("" + +str). Về cơ bản, nó kiểm tra xem chuỗi có phải là kết quả của việc xâu chuỗi một số JS hay không. Biết điều này, chúng ta cũng có thể thấy một vấn đề: thử nghiệm vượt qua 0.000001nhưng không thành công 0.0000001, đó là khi 1e-7vượt qua thay thế. Tương tự cho số lượng rất lớn.
GregRos


4

Trích dẫn:

isNaN (num) // trả về true nếu biến KHÔNG chứa số hợp lệ

không hoàn toàn đúng nếu bạn cần kiểm tra các khoảng trắng ở đầu / cuối - ví dụ: khi cần một số lượng chữ số nhất định và bạn cần lấy, '1111' chứ không phải '111' hoặc '111' để lấy mã PIN đầu vào.

Sử dụng tốt hơn:

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

Các giá trị '-1', '0.1''1e10'tất cả trả về false. Hơn nữa, các giá trị lớn hơn vô cực dương hoặc nhỏ hơn vô cực âm trả về giá trị true, trong khi chúng có thể trả về giá trị false.
Rudey

4

Tại sao việc triển khai của jQuery không đủ tốt?

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

Michael đã đề xuất một cái gì đó như thế này (mặc dù tôi đã đánh cắp phiên bản thay đổi của "user1691651 - John" tại đây):

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

Sau đây là một giải pháp với hiệu suất rất có thể xấu, nhưng kết quả chắc chắn. Đó là một chi tiết được tạo ra từ triển khai jQuery 1.12.4 và câu trả lời của Michael, với một kiểm tra bổ sung cho các khoảng trắng ở đầu / cuối (vì phiên bản của Michael trả về đúng cho các số có khoảng trắng ở đầu / cuối):

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));
};

Phiên bản sau có hai biến mới. Người ta có thể đi xung quanh một trong số đó, bằng cách làm:

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));
};

Tôi chưa từng thử nghiệm bất kỳ thứ nào trong số này, bằng các cách khác ngoài kiểm tra thủ công một vài trường hợp sử dụng mà tôi sẽ gặp phải với tình trạng khó khăn hiện tại của mình, đó là tất cả những thứ rất chuẩn. Đây là một tình huống "đứng trên vai người khổng lồ".


4

Nó không hợp lệ đối với TypeScript như:

declare function isNaN(number: number): boolean;

Đối với TypeScript, bạn có thể sử dụng:

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


3

Chà, tôi đang sử dụng cái này tôi đã làm ...

Nó đã hoạt động cho đến nay:

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

Nếu bạn phát hiện ra bất kỳ vấn đề với nó, xin vui lòng cho tôi biết.


12
Điều này cho kết quả sai cho chuỗi rỗng, mảng trống, false và null.
Ori

2
Không phải là một ba bằng nhau?
to nướng_flakes

1
Trong ứng dụng của tôi, chúng tôi chỉ cho phép az AZ và 0-9 ký tự. Tôi thấy các công việc trên hoạt động trừ khi chuỗi bắt đầu bằng 0xnn và sau đó chuỗi sẽ trả về dưới dạng số khi không nên. Tôi đã đăng trong một nhận xét bên dưới để định dạng không bị ảnh hưởng.
rwheadon

6
bạn chỉ có thể làm 'giá trị trả về% 1 === 0'
Brian Schermerhorn

Chỉ cần làmreturn !isNaN(parseInt(value, 10));
DarkNeuron

3

Nếu bất cứ ai đã bỏ xa điều này, tôi đã dành một chút thời gian để hack điều này khi cố gắng vá khoảnh khắc.js ( https://github.com/moment/moment ). Đây là thứ mà tôi đã lấy từ nó:

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

Xử lý các trường hợp sau:

Thật! :

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

Sai! :

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()))

Trớ trêu thay, người mà tôi đang vật lộn nhất:

isNumeric(new Number(1)) => false

Mọi góp ý đều được chào đón. :]


2
Còn về isNumeric(' ')isNumeric('')?
Alex Cory

Tôi sẽ thêm && (val.replace(/\s/g,'') !== '') //Empty && (val.slice(-1) !== '.') //Decimal without Numbervào để giải quyết vấn đề được đề cập ở trên và một vấn đề mà tôi đã có.
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 ...
}

Cảm ơn bạn, câu trả lời tuyệt vời!
M.Abulsoud

3

2019: Bao gồm các ví dụ ES3, ES6 và TypeScript

Có thể điều này đã được thử lại quá nhiều lần, tuy nhiên hôm nay tôi cũng đã chiến đấu với câu hỏi này và muốn đăng câu trả lời của mình, vì tôi không thấy bất kỳ câu trả lời nào khác chỉ đơn giản hoặc triệt để:

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);

Bản đánh máy

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

Điều này có vẻ khá đơn giản và bao gồm tất cả các cơ sở tôi thấy trên nhiều bài đăng khác và tự nghĩ ra:

// 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);

Bạn cũng có thể thử isNumeric chức năng và chỉ qua trong các trường hợp sử dụng này và quét "đúng" cho tất cả chúng.

Hoặc, để xem các giá trị mà mỗi trả về:

Kết quả của mỗi thử nghiệm đối với <code> isNumeric () </ code>


3

2019: Kiểm tra tính hợp lệ số thực tế và chặt chẽ

Thông thường, number số hợp lệ 'có nghĩa là số Javascript không bao gồm NaN và Infinity, tức là' số hữu hạn '.

Để kiểm tra tính hợp lệ bằng số của một giá trị (ví dụ từ nguồn bên ngoài), bạn có thể xác định theo kiểu 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;
}

và sử dụng nó theo cách này:

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

2

PFB giải pháp làm việc:

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

2

Hãy tự cứu mình khỏi đau đầu khi cố gắng tìm một giải pháp "tích hợp".

Không có câu trả lời hay, và câu trả lời được đánh giá cao trong chủ đề này là sai.

npm install is-number

Trong JavaScript, không phải lúc nào cũng đơn giản như cần kiểm tra một cách đáng tin cậy nếu một giá trị là một số. Thông thường, các nhà phát triển sử dụng +, - hoặc Number () để truyền giá trị chuỗi cho một số (ví dụ: khi các giá trị được trả về từ đầu vào của người dùng, khớp chính tả, trình phân tích cú pháp, v.v.). Nhưng có nhiều trường hợp cạnh không trực quan mang lại kết quả bất ngờ:

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

1

Gần đây tôi đã viết một bài viết về các cách để đảm bảo một biến là một số hợp lệ: https://github.com/jehrifeahsa/artifacts/blob/master/2018/typescript_num_hack.md Bài viết giải thích cách đảm bảo dấu phẩy động hoặc số nguyên, nếu đó là quan trọng ( +xso với ~~x).

Bài báo giả định biến là một stringhoặc một numberđể bắt đầu và trimcó sẵn / đa dạng. Sẽ không khó để mở rộng nó để xử lý các loại khác. Đây là thịt của nó:

// 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

Nỗ lực của tôi ở một chút khó hiểu, Pherinois không phải là giải pháp tốt nhất

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

Nó không quá tệ, hai xấu nó không hoạt động đối với bất kỳ ký hiệu không thập phân nào, chẳng hạn như (1) ký hiệu khoa học và (2) ký hiệu không căn cứ-10, chẳng hạn như bát phân ( 042) và thập lục phân ( 0x45f)
Domi

Điều này không trả lời cho câu hỏi tìm kiếm một giá trị số, nó chỉ tìm một số nguyên.
Jeremy

0

Trong ứng dụng của tôi, chúng tôi chỉ cho phép az AZ và 0-9 ký tự. Tôi đã tìm thấy câu trả lời ở trên bằng cách sử dụng " chuỗi % 1 === 0" trừ khi chuỗi bắt đầu bằng 0xnn (như 0x10) và sau đó nó sẽ trả về dưới dạng số khi chúng tôi không muốn. Cái bẫy đơn giản sau đây trong kiểm tra số của tôi dường như thực hiện thủ thuật trong các trường hợp cụ thể của chúng tôi.

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;}

Cảnh báo : Điều này có thể đang khai thác một lỗi lâu đời trong Javascript và Actioncript [Số ("1" + the_ chuỗi)% 1 === 0)], tôi không thể nói điều đó, nhưng đó chính xác là những gì chúng ta cần.


Tại sao đó là một lỗi trong JavaScript?
Bergi

Tôi chỉ đơn giản là không thấy hành vi tương tự với một giải pháp tương tự trong perl hoặc C, và vì tôi không phải là nhà phát triển ngôn ngữ lập trình cho javascript hoặc Actioncript nên tôi không biết liệu hành vi tôi đang trải qua có thực sự có chủ ý hay không.
rwheadon

Vâng, javascript hơi cẩu thả về việc truyền kiểu ẩn, nhưng một khi bạn biết rằng bạn có thể dễ dàng hiểu cách thức hoạt động của nó. Bạn đang truyền chuỗi thành số (bằng cách gọi % 1thao tác số trên chúng) và điều đó sẽ diễn giải chuỗi dưới dạng hex hoặc float.
Bergi

0

Giải pháp của tôi:

// 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;
 };

Bạn có thể thêm các điều kiện bổ sung bên trong vòng lặp, để phù hợp với nhu cầu cụ thể của bạn.


0

Bạn có thể sử dụng các loại, như với librar y, để kiểm tra thời gian tĩnh, biên dịch. Tất nhiên không hữu ích lắm cho đầu vào của người dùng.

// @flow

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

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

0

Đây là một lớp lót để kiểm tra xem sNumgiá trị số có hợp lệ không; nó đã được thử nghiệm cho nhiều loại đầu vào:

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

0

Chỉ cần sử dụng isNaN(), điều này sẽ chuyển đổi chuỗi thành một số và nếu nhận được một số hợp lệ , sẽ trả về false...

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

0

Tôi đang sử dụng như sau:

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

Hoạt động tương đối tốt là nhiều trường hợp, nhưng không trường hợp như thế 1..1, 1,1, -32.1.12, và quan trọng hơn không undefinedNaN. Nếu bạn vượt qua undefinedhoặc một NaNđiều đó sẽ trả lại cho bạn một tích cực sai nói rằng đó là một con số.
Jeremy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.