Làm cách nào để kiểm tra xem một biến có phải là số nguyên trong JavaScript không?


405

Làm cách nào để kiểm tra xem một biến có phải là số nguyên trong JavaScript hay không và đưa ra cảnh báo nếu không phải là biến? Tôi đã thử điều này, nhưng nó không hoạt động:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>

2
Một điều tích cực ở đây là sử dụng parseInt.
Paul

2
jsben.ch/#/htLVw - điểm chuẩn cho những cách phổ biến để thực hiện
EscapeNetscape

Tất cả các câu trả lời ở đây thực sự đã lỗi thời. Hôm nay, tôi khuyên bạn nên bám vào Number.isIntegerđó là cách ít hack nhất.
Benjamin Gruenbaum

@Benjamim nếu số đó là một chuỗi có thể được chuyển đổi thành số nguyên thì sao? và trong HTML, mọi thứ đều là một chuỗi .. vì vậy Number.isInteger ("69") là sai
joedotnot

Câu trả lời:


344

Sử dụng toán tử === ( đẳng thức nghiêm ngặt ) như dưới đây,

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")

95
cái này tính NaN là một số nguyên. cũng thực hiện tồi tệ hơn so với phương pháp của tôi. jsperf.com/numbers-and-integers
Blake Regalia

2
nếu bạn chạy ví dụ của mình thông qua đoạn mã trên, nó sẽ cảnh báo một số nguyên và một số nguyên khác không phải là số nguyên ... trong trường hợp NaN cũng là loại NaN khác với loại giá trị trả về của pareInt () .....
pranag

1
bạn có thể xây dựng một chút? "ví dụ" chỉ chứng minh rằng sử dụng parseInt mang lại hiệu suất kém hơn so với sử dụng toán tử mô đun và từ khóa typeof. nhưng tôi hiểu ý của bạn lúc này về (NaN! = NaN)
Blake Regalia

4
@connorbode trong javascript tất cả các số có cùng loại (không có số float hoặc double), do đó, 2.0 === 2số thập phân không cần thiết chỉ là một đại diện khác nhau của cùng một số, do đó, parseInt(2.0) === 2.0tương đương với số parseInt(2) === 2đó là đúng
Michael Theriot

1
@BlakeRegalia: Mặc dù nhanh, phương pháp của anh ta không vượt qua tất cả các giá trị có thể có từ câu trả lời này: stackoverflow.com/a/14794066/843732
c00000fd

506

Điều đó phụ thuộc, bạn cũng muốn truyền chuỗi như các số nguyên tiềm năng không?

Điều này sẽ làm:

function isInt(value) {
  return !isNaN(value) && 
         parseInt(Number(value)) == value && 
         !isNaN(parseInt(value, 10));
}

Với các hoạt động của Bitwise

Phân tích và kiểm tra đơn giản

function isInt(value) {
  var x = parseFloat(value);
  return !isNaN(value) && (x | 0) === x;
}

Đoản mạch và lưu thao tác phân tích cú pháp:

function isInt(value) {
  if (isNaN(value)) {
    return false;
  }
  var x = parseFloat(value);
  return (x | 0) === x;
}

Hoặc có lẽ cả hai trong một lần bắn:

function isInt(value) {
  return !isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value))
}

Các xét nghiệm:

isInt(42)        // true
isInt("42")      // true
isInt(4e2)       // true
isInt("4e2")     // true
isInt(" 1 ")     // true
isInt("")        // false
isInt("  ")      // false
isInt(42.1)      // false
isInt("1a")      // false
isInt("4e2a")    // false
isInt(null)      // false
isInt(undefined) // false
isInt(NaN)       // false

Đây là câu đố: http://jsfiddle.net/opfyrqwp/28/

Hiệu suất

Thử nghiệm cho thấy giải pháp ngắn mạch có hiệu suất tốt nhất (ops / giây).

// Short-circuiting, and saving a parse operation
function isInt(value) {
  var x;
  if (isNaN(value)) {
    return false;
  }
  x = parseFloat(value);
  return (x | 0) === x;
}

Đây là một điểm chuẩn: http://jsben.ch/#/htLVw

Nếu bạn thích một hình thức ngắn mạch, khó hiểu của ngắn mạch:

function isInt(value) {
  var x;
  return isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
}

Tất nhiên, tôi khuyên bạn nên để công cụ khai thác xử lý việc đó.


4
@krisk - Nâng cấp cho nhiều giải pháp. Đồng thời thực hiện thử nghiệm nhanh trên 4 biến thể bạn cung cấp: jsperf.com/tfm-is-integer - và xác định rằng giải pháp ngắn mạch có hiệu suất tốt nhất.
tfmontague

1
Nó trả về sai vào ngày 2099999999999999: - (
jkucharovic

1
@jkucharovic toán tử bitwise OR là thủ phạm. Sử dụng phiên bản không bitwise sẽ trả về true.
krisk

1
Điều này làm cho '2.' đánh giá là đúng
cyberwombat

1
@cyberwombat cũng là số thập phân 2.0 :-)
Kuba Beránek

120

Giả sử bạn không biết gì về biến trong câu hỏi, bạn nên thực hiện phương pháp này:

if(typeof data === 'number') {
    var remainder = (data % 1);
    if(remainder === 0) {
        // yes, it is an integer
    }
    else if(isNaN(remainder)) {
        // no, data is either: NaN, Infinity, or -Infinity
    }
    else {
        // no, it is a float (still a number though)
    }
}
else {
    // no way, it is not even a number
}

Nói một cách đơn giản:

if(typeof data==='number' && (data%1)===0) {
    // data is an integer
}

8
Ý anh là gì? Điều này kiểm tra các loại dữ liệu trong javascript, "1.0"là một chuỗi và do đó không phải là một số. Mặt khác 1sẽ là giá trị của một biến nếu bạn đặt nó như vậy var my_var=1.0;, được xác định chính xác bởi hàm này là một số nguyên.
Blake Regalia

4
Sớm thôi, Number.isInteger()sẽ hoạt động ... cho đến lúc đó, đây là một cách tốt để làm điều đó
Claudiu

Number.isInteger không hoạt động với tôi. Tôi phải làm gì đó sai. Giải pháp của Blake% 1 hoạt động hoàn hảo.
mcmacerson

104

Number.isInteger() dường như là con đường để đi

MDN cũng đã cung cấp polyfill sau cho các trình duyệt không hỗ trợ Number.isInteger(), chủ yếu là tất cả các phiên bản IE.

Liên kết đến trang MDN

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && 
           isFinite(value) && 
           Math.floor(value) === value;
};

2
MDN có thử nghiệm trên 9007199254740992 loại bỏ
Bernhard Döbler

2
Đây là câu trả lời đơn giản và "chính xác" nhất. Ý tôi là, JavaScript đã có phương pháp để kiểm tra tính nguyên. Không cần phải viết một cái mới. Kiểm tra isNaN () cho số lượng, không phải số nguyên.
globalewalldesk

66

Bạn có thể kiểm tra xem số có còn lại không:

var data = 22;

if(data % 1 === 0){
   // yes it's an integer.
}

Xin lưu ý bạn, nếu đầu vào của bạn cũng có thể là văn bản và bạn muốn kiểm tra trước thì không phải vậy, sau đó bạn có thể kiểm tra loại trước:

var data = 22;

if(typeof data === 'number'){
     // yes it is numeric

    if(data % 1 === 0){
       // yes it's an integer.
    }
}

3
@Erwinus: Chạy 0 % 1 === 0trong bảng điều khiển. Nó trả về truenhư 0 % 1trả về 0.
Không có

Bạn đã thử nó trong IE ;-)
Codebeat

1
@Erwinus: 0 % 1trả về 0trong chế độ tương thích IE9, IE8 và IE7.
Không có

Hãy thử nó trong một IE cũ thực sự. bên cạnh đó luôn là một cách tốt để lập trình để kiểm tra số 0 và không dựa vào trình duyệt phải làm gì.
Codebeat

62
@Erwinus: Tôi nghĩ rằng bạn có sự thật lẫn lộn. Một phép chia cho số 0 được tạo ra khi bạn chia cho số 0 chứ không phải khi bạn chia số không cho một số. Không có gì để làm với phiên bản IE cả.
Không có

22

Bạn có thể sử dụng một biểu thức chính quy đơn giản:

function isInt(value) {
    var er = /^-?[0-9]+$/;
    return er.test(value);
}

15

Trước hết, NaN là một "số" (vâng tôi biết điều đó thật kỳ lạ, chỉ cần cuộn với nó) chứ không phải là "chức năng".

Bạn cần kiểm tra cả hai nếu loại biến là một số và để kiểm tra số nguyên tôi sẽ sử dụng mô đun.

alert(typeof data === 'number' && data%1 == 0);

2
nên là: alert (typeof data == 'number' && (data == 0 || data% 1 == 0)); để tránh chia cho số không.
Codebeat

19
@Erwinus 0% 1 vẫn được chia cho 1.
Phil

@Phil, (0 == 0 || 0 % 1 == 0)sẽ đánh giá true.
tomekwi

Oh, nhân tiện 0 % 1 == 0cũng đánh giá true! %không phải là chia!
tomekwi

13

Cẩn thận trong khi sử dụng

số% 1

chuỗi rỗng ('') hoặc boolean (đúng hoặc sai) sẽ trả về dưới dạng số nguyên. Bạn có thể không muốn làm điều đó

false % 1 // true
'' % 1 //true

Number.isInteger (dữ liệu)

Number.isInteger(22); //true
Number.isInteger(22.2); //false
Number.isInteger('22'); //false

xây dựng chức năng trong trình duyệt. Hỗ trợ hiệu quả các trình duyệt cũ hơn

Lựa chọn thay thế:

Math.round(num)=== num

Tuy nhiên, Math.round () cũng sẽ thất bại đối với chuỗi rỗng và boolean


8

Để kiểm tra xem số nguyên như poster muốn:

if (+data===parseInt(data)) {return true} else {return false}

thông báo + trước dữ liệu (chuyển đổi chuỗi thành số) và chính xác ===.

Dưới đây là ví dụ:

data=10
+data===parseInt(data)
true

data="10"
+data===parseInt(data)
true

data="10.2"
+data===parseInt(data)
false

6
Đây có vẻ là giải pháp thông minh nhất cho trường hợp của tôi (tôi không bận tâm nếu đó là số nguyên trong chuỗi). Tuy nhiên: tại sao không đi return (+data===parseInt(data))?
Thụy Sĩ


6

Giải pháp tiền ECMAScript-6 đơn giản và gọn gàng nhất (cũng đủ mạnh để trả về false ngay cả khi một giá trị không phải là số như chuỗi hoặc null được truyền cho hàm) sẽ như sau:

function isInteger(x) { return (x^0) === x; } 

Giải pháp sau đây cũng sẽ hiệu quả, mặc dù không thanh lịch như giải pháp trên:

function isInteger(x) { return Math.round(x) === x; }

Ghi chú rằng Math.ceil () hoặc Math.floor () có thể được sử dụng tốt như nhau (thay vì Math.round ()) trong triển khai trên.

Hay cách khác:

function isInteger(x) { return (typeof x === 'number') && (x % 1 === 0); }

Một giải pháp không chính xác khá phổ biến là như sau:

function isInteger(x) { return parseInt(x, 10) === x; }

Mặc dù cách tiếp cận dựa trên parseInt này sẽ hoạt động tốt đối với nhiều giá trị của x, một khi x trở nên khá lớn, nó sẽ không hoạt động đúng. Vấn đề là parseInt () ép tham số đầu tiên của nó thành một chuỗi trước khi phân tích cú pháp các chữ số. Do đó, một khi số lượng trở nên đủ lớn, biểu diễn chuỗi của nó sẽ được trình bày dưới dạng hàm mũ (ví dụ: 1e + 21). Theo đó, parseInt () sau đó sẽ cố phân tích 1e + 21, nhưng sẽ dừng phân tích cú pháp khi đến ký tự e và do đó sẽ trả về giá trị là 1. Quan sát:

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

> parseInt(1000000000000000000000, 10) === 1000000000000000000000
false

6

Tại sao không ai nhắc đến Number.isInteger()?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger

Hoạt động hoàn hảo cho tôi và giải quyết vấn đề với số NaNbắt đầu.


1
Lưu ý rằng đây là ES6, vì vậy các trình duyệt cũ hơn (như IE <= 11) không hỗ trợ nó. Các tài liệu ở trên cung cấp một polyfill.
giám mục

Ai đó đã đề cập Number.isInteger(), 3,5 năm trước bạn: stackoverflow.com/a/27424770/5208540
Alex Stragies

nếu chúng ta sẽ bắt một giá trị từ một đầu vào thì hãy kiểm tra, Number.isInteger sẽ luôn trả về false vì giá trị đầu vào là của kiểu dữ liệu chuỗi
Shinigamae

6

Trong ES6 2 phương thức mới được thêm vào cho Object Object.

Trong đó phương thức Number.isInteger () trả về true nếu đối số là số nguyên.

Ví dụ sử dụng:

Number.isInteger(10);        // returns true
Number.isInteger(10.5);      // returns false

4

Tiêu chuẩn ECMA-262 6.0 (ES6) bao gồm Number.isInteger chức năng .

Để thêm hỗ trợ cho trình duyệt cũ, tôi khuyên bạn nên sử dụng giải pháp mạnh mẽ và được cộng đồng hỗ trợ từ:

https://github.com/paulmillr/es6-shim

đó là thư viện polyfills ES6 thuần túy .

Lưu ý rằng lib này yêu cầu es5-shim, chỉ cần làm theo README.md.


4

Bạn có thể thử Number.isInteger(Number(value))nếu valuecó thể là một số nguyên ở dạng chuỗi, vdvar value = "23" và bạn muốn đánh giá này true. Tránh cố gắng Number.isInteger(parseInt(value))vì điều này sẽ không luôn trả về giá trị chính xác. ví dụ nếu var value = "23abc"và bạn sử dụngparseInt thực hiện, nó vẫn sẽ trả về đúng.

Nhưng nếu bạn muốn các giá trị nguyên nghiêm ngặt thì có lẽ Number.isInteger(value)nên thực hiện thủ thuật.


1
Lưu ý rằng điều này không được IE hỗ trợ; như đã nêu ở đây trong tài liệu tôi đã dừng đoạn mã của mình vì điều này đặc biệt là nếu var bạn đang kiểm tra không được xác định
mikewasmike

4
var x = 1.5;
if(!isNaN(x)){
 console.log('Number');
 if(x % 1 == 0){
   console.log('Integer');
 }
}else {
 console.log('not a number');
}

3
Sau 29 câu trả lời, người ta sẽ mong đợi thêm một chút lời giải thích để làm cho câu trả lời của bạn nổi bật ...
brasofilo

3

Kiểm tra xem biến có bằng với biến đó được làm tròn thành một số nguyên không, như sau:

if(Math.round(data) != data) {
    alert("Variable is not an integer!");
}

Bạn có thể dễ dàng khắc phục vấn đề của chức năng này với trở về truecho NaN, bằng cách đơn giản thay đổi !=để !==và đảo ngược các ifkhối. Điều này hoạt động vì NaNlà giá trị duy nhất trong JavaScript không bằng chính nó. Ví dụ: mã mới phải làif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99

3

Bên cạnh đó , Number.isInteger(). Có lẽ Number.isSafeInteger()là một lựa chọn khác ở đây bằng cách sử dụng ES6 được chỉ định.

Để polyfill Number.isSafeInteger(..)trong trình duyệt trước ES6:

Number.isSafeInteger = Number.isSafeInteger || function(num) {
    return typeof num === "number" && 
           isFinite(num) && 
           Math.floor(num) === num &&
           Math.abs( num ) <= Number.MAX_SAFE_INTEGER;
};

3

Number.isInteger() là cách tốt nhất nếu trình duyệt của bạn hỗ trợ nó, nếu không, tôi nghĩ có rất nhiều cách để đi:

function isInt1(value){
  return (value^0) === value
}

hoặc là:

function isInt2(value){
  return (typeof value === 'number') && (value % 1 === 0); 
}

hoặc là:

function isInt3(value){
  return parseInt(value, 10) === value; 
}

hoặc là:

function isInt4(value){
  return Math.round(value) === value; 
}

bây giờ chúng ta có thể kiểm tra kết quả:

var value = 1
isInt1(value)   // return true
isInt2(value)   // return true
isInt3(value)   // return true
isInt4(value)   // return true

var value = 1.1
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

var value = 1000000000000000000
isInt1(value)   // return false
isInt2(value)   // return true
isInt3(value)   // return false
isInt4(value)   // return true

var value = undefined
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

var value = '1' //number as string
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

Vì vậy, tất cả các phương thức này đều hoạt động, nhưng khi số lượng rất lớn, toán tử parseInt và ^ sẽ không hoạt động tốt.


3

Hãy thử điều này:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}

Number.isInteger () không được hỗ trợ trong tất cả các phiên bản trình duyệt IE.
SKR

2

Bạn có thể sử dụng chức năng này:

function isInteger(value) {
    return (value == parseInt(value));
}

Nó sẽ trả về true ngay cả khi giá trị là một chuỗi chứa giá trị nguyên.
Vì vậy, kết quả sẽ là:

alert(isInteger(1)); // true
alert(isInteger(1.2)); // false
alert(isInteger("1")); // true
alert(isInteger("1.2")); // false
alert(isInteger("abc")); // false

2

Cách tiếp cận của tôi:

a >= 1e+21Kiểm tra chỉ có thể vượt qua cho một giá trị phải là một số một giá trị rất lớn. Điều này sẽ bao gồm tất cả các trường hợp chắc chắn, không giống như các giải pháp khác đã được cung cấp trong cuộc thảo luận này.

a === (a|0)Nếu đối số của hàm đã cho là chính xác (===) giống với giá trị được biến đổi theo bit, điều đó có nghĩa là đối số là một số nguyên.

a|0sẽ trả về 0bất kỳ giá trị nào của số ađó không phải là số và nếu athực sự là một số, nó sẽ loại bỏ mọi thứ sau dấu thập phân, vì vậy 1.0001sẽ trở thành1

function isInteger(a){
    return a >= 1e+21 ? true : a === (a|0)
}

/// tests ///////////////////////////
[
  1,                        // true
  1000000000000000000000,   // true
  4e2,                      // true
  Infinity,                 // true
  1.0,                      // true
  1.0000000000001,          // false
  0.1,                      // false
  "0",                      // false
  "1",                      // false
  "1.1",                    // false
  NaN,                      // false
  [],                       // false
  {},                       // false
  true,                     // false
  false,                    // false
  null,                     // false
  undefined                 // false
].forEach( a => console.log(typeof a, a, isInteger(a)) )


1
Ý tưởng tốt! Tôi cũng thích rằng bạn đã cho thấy các thử nghiệm của mình nhưng thật không may, điều này không xem xét giá trị Chuỗi là "0".
Jammer

Hey @vsync, Không cố ý. Tôi đã upvote ban đầu nhưng quyết định hoàn nguyên nó do nhận xét trước đó của tôi. Tôi đã vô tình nhấp đúp vào nó hoặc một cái gì đó.
Jammer

1

Bạn có thể sử dụng regrec cho việc này:

function isInteger(n) {
    return (typeof n == 'number' && /^-?\d+$/.test(n+''));
}


1

Sử dụng |toán tử:

(5.3 | 0) === 5.3 // => false
(5.0 | 0) === 5.0 // => true

Vì vậy, một chức năng kiểm tra có thể trông như thế này:

var isInteger = function (value) {
  if (typeof value !== 'number') {
    return false;
  }

  if ((value | 0) !== value) {
    return false;
  }

  return true;
};

1

Điều này sẽ giải quyết thêm một kịch bản ( 121. ), một dấu chấm ở cuối

function isInt(value) {
        var ind = value.indexOf(".");
        if (ind > -1) { return false; }

        if (isNaN(value)) {
            return false;
        }

        var x = parseFloat(value);
        return (x | 0) === x;

    }

1

Đối với các giá trị nguyên dương không có dấu phân cách:

return ( data !== '' && data === data.replace(/\D/, '') );

Kiểm tra 1. nếu không trống và 2. nếu giá trị bằng kết quả của việc thay thế char không có chữ số trong giá trị của nó.


1

Ok có điểm trừ, vì không mô tả ví dụ của tôi, vì vậy nhiều ví dụ hơn :):

Tôi sử dụng biểu thức chính quy và phương pháp kiểm tra:

var isInteger = /^[0-9]\d*$/;

isInteger.test(123); //true
isInteger.test('123'); // true
isInteger.test('sdf'); //false
isInteger.test('123sdf'); //false

// If u want to avoid string value:
typeof testVal !== 'string' && isInteger.test(testValue);

Có thể trừ đi vì kiểm tra không phải là một chức năng.
imlokesh

@imlokesh Ý bạn là gì "không phải là một chức năng"? Tôi đã viết tôi sử dụng "phương pháp thử nghiệm".
Vasyl Gutnyk

@imlokesh không có vấn đề gì, tôi chỉ hỏi U vì tôi đã sử dụng nó trong sản xuất :) và tôi nghĩ rằng bạn đã tìm thấy một số lỗi :)
Vasyl Gutnyk

1

bạn cũng có thể thử nó theo cách này

var data = 22;
if (Number.isInteger(data)) {
    console.log("integer");
 }else{
     console.log("not an integer");
 }

hoặc là

if (data === parseInt(data, 10)){
    console.log("integer");
}else{
    console.log("not an integer");
}

Điều này sẽ tạo ra kết quả sai cho data=22.5;. Cả hai chi nhánh đều có console.log("not an integer"):: S
Colin Breame

0

Tôi đã phải kiểm tra xem một biến (chuỗi hoặc số) có phải là số nguyên không và tôi đã sử dụng điều kiện này:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a);
}

http://jsfiddle.net/e267369d/1/

Một số câu trả lời khác có một giải pháp tương tự (dựa vào parseFloatkết hợp với isNaN), nhưng tôi nên thẳng thắn hơn và tự giải thích.


Chỉnh sửa: Tôi phát hiện ra rằng phương thức của tôi thất bại đối với các chuỗi chứa dấu phẩy (như "1,2") và tôi cũng nhận ra rằng trong trường hợp cụ thể của mình, tôi muốn hàm bị lỗi nếu một chuỗi không phải là số nguyên hợp lệ (không thành công trên bất kỳ dấu phẩy nào , thậm chí là 1). Vì vậy, đây là chức năng của tôi Mk II:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a) && (typeof a != 'string' || (a.indexOf('.') == -1 && a.indexOf(',') == -1));
}

http://jsfiddle.net/e267369d/3/

Tất nhiên trong trường hợp bạn thực sự cần hàm để chấp nhận số nguyên float (1.0 thứ), bạn luôn có thể loại bỏ điều kiện dấu chấm a.indexOf('.') == -1.

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.