Làm cách nào để biến NaN từ parseInt thành 0 cho một chuỗi rỗng?


298

Có thể bằng cách nào đó trả về 0 thay vì NaNkhi phân tích giá trị trong JavaScript?

Trong trường hợp chuỗi rỗng parseInttrả về NaN.

Có thể làm một cái gì đó như thế trong JavaScript để kiểm tra NaNkhông?

var value = parseInt(tbb) == NaN ? 0 : parseInt(tbb)

Hoặc có thể có một chức năng hoặc plugin jQuery khác có thể làm điều gì đó tương tự?


72
FYI , NaN != NaN. Bạn sẽ cần isNaN(value).
pimvdb

28
Vâng, không có hai vú em nào giống nhau;)
James P.

3
Chức năng gọi parseInt()hai lần (trong NaNtrường hợp không thành công / bình thường ) không bao giờ là một ý tưởng hay. Ngoài sự không hiệu quả, đối với người không sẵn sàng nếu bất cứ điều gì được thông qua tbblà một cuộc gọi chức năng với tác dụng phụ thì thật tồi tệ. Tôi sẽ không sử dụng bất kỳ giải pháp nào ở đây, nơi tôi thấy parseInt()hai lần.
JonBrave

Câu trả lời:


756
var s = '';

var num = parseInt(s) || 0;

Khi không được sử dụng với các giá trị boolean, ||toán tử OR ( ) logic trả về biểu thức đầu tiên ( parseInt(s)) nếu nó có thể được ước tính là true, nếu không, nó trả về biểu thức thứ hai (0). Giá trị trả về của parseInt('')là NaN. NaN ước tính là sai, vì vậy numkết thúc được đặt thành 0.


6
Điều này sẽ không hoạt động nếu s = "4s"; (nó trả về 4 ... không chính xác ...)
markzzz

1
Hàm parseInt trong js phân tích bất kỳ số nào trong chuỗi
ali youhannaei

26
@markzzz Đọc lại câu hỏi. OP hỏi: " Bằng cách nào đó có thể trả về 0 thay vì NaN ". OP không muốn kiểm tra xem liệu chuỗi cụ thể có thể phân tích cú pháp thành int. OP muốn nhận 0thay vì NaN. Điều này được giải quyết bằng mã của Matt một cách hoàn hảo.
trejder

2
@markzzzvar nextIphone = parseInt("4S") + 1; // wow it works!
Không phân tâm

2
@Matthew vui lòng sử dụng thuật ngữ "giả" hoặc "trung thực" . vì NaN === sai là sai! nhưng Boolean (NaN) === Boolean (sai) là đúng. logic OR trả về biểu thức đầu tiên nếu nó có thể được đánh giá là "trung thực"
Pablo Recalde

52

Bạn cũng có thể sử dụng isNaN()chức năng:

var s = ''
var num = isNaN(parseInt(s)) ? 0 : parseInt(s)

12
Tại sao gọi parseInt(s)hai lần? Hơn nữa, nó phải làparseInt(s, 10)
Dexygen

2
@GeorgeJempty Một cơ số của "10" là mặc định; tham số đó là tùy chọn. Điểm tốt khi gọi parseInt()hai lần mặc dù.
Mùa thu Leonard

8
@AutumnLeonard đây chỉ là loại đúng. Nếu chuỗi của bạn bắt đầu bằng 0 thì giả sử số đó ở định dạng bát phân, do đó parseInt ('077') cung cấp cho bạn 63. Điều này có thể dẫn đến rất khó tìm lỗi, do đó bạn phải luôn chỉ định tham số thứ hai. xem ví dụ stackoverflow.com/questions/8763396/ trên
chuck258

22

Tôi ngạc nhiên khi không thấy ai nhắc đến việc sử dụng Number(). Được cấp, nó sẽ phân tích số thập phân nếu được cung cấp, do đó sẽ hành động khác với parseInt(), tuy nhiên, nó đã giả sử cơ sở 10 và sẽ biến "" hoặc thậm chí "" thành 0.


1
Có, rất tiện để đọc từ localStorage: Number (localStorage.getItem ('appBanner.count')) + 1
Philip Murphy

Mặc dù nó hoạt động cho câu hỏi như đã được hỏi, nó vẫn trả về NaN cho các ký tự không phải khoảng trắng số
Kyle Delaney

9

Đối với những người không bị hạn chế parseInt, bạn có thể sử dụng toán tử bitwise OR (gọi ngầm ToInt32cho toán hạng của nó).

var value = s | 0;

// NaN | 0     ==>> 0
// ''  | 0     ==>> 0
// '5' | 0     ==>> 5
// '33Ab' | 0  ==>> 0
// '0x23' | 0  ==>> 35
// 113 | 0     ==>> 113
// -12 | 0     ==>> -12
// 3.9 | 0     ==>> 3

Lưu ý: ToInt32khác với parseInt. (tức là parseInt('33Ab') === 33)


Nhưng : '10000000000' | 0 === 1410065408.
trincot

@trincot có, mọi giá trị> = Math.pow(2, 31)sẽ tràn.
Ahmad Ibrahim

8

Vấn đề

Các câu trả lời khác không tính đến sai 0lệch, và do đó, sau đây sẽ là 20 thay vì 0:

const myNumber = parseInt('0') || 20; // 20

Giải pháp

Tôi đề xuất một hàm trợ giúp, giải quyết hầu hết các vấn đề:

function getNumber({ value, defaultValue }) {
  const num = parseInt(value, 10);
  return isNaN(num) ? defaultValue : num;
}

Hàm trợ giúp sẽ cho kết quả như sau:

getNumber({ value: "0", defaultValue: 20 }); // 0
getNumber({ value: "2", defaultValue: 20 }); // 2
getNumber({ value: "2.2", defaultValue: 20 }); // 2
getNumber({ value: "any string", defaultValue: 20 }); // 20
getNumber({ value: undefined, defaultValue: 20 }); // 20
getNumber({ value: null, defaultValue: 20 }); // 20
getNumber({ value: NaN, defaultValue: 20 }); // 20
getNumber({ value: false, defaultValue: 20 }); // 20
getNumber({ value: true, defaultValue: 20 }); // 20

2
Vui lòng gửi một cơ số đến parseInt : parseInt(string, radix), hãy xem xét điều này: parseInt("0x10") === 16Cũng parseInt("010")có thể mang lại 8trong một số trình duyệt
andlrc

2
Nếu bạn đã phụ thuộc vào lodash cho các công cụ khác, thì có một defaultTochức năng tiện dụng chỉ thực hiện điều này: _.defaultTo(NaN, -1)trả về -1, nhưng _.defaultTo(0, -1);trả về 0.
waldyrious

Đây là một điểm tuyệt vời! Bạn chỉ có thể dựa vào | | ở cuối để cung cấp mặc định chính xác khi mặc định ưa thích của bạn là ZERO (được cấp, đây là những gì OP muốn). Như bạn đã đề cập, do tính chất giả mạo của đầu vào '0', nó được coi là đầu vào không hợp lệ trong trường hợp này và câu lệnh sẽ trả về giá trị mặc định thay vào đó (có thể không như mong đợi!)
JonathanDavidArndt

Chắc chắn bạn nên sử dụng một const thay vì gọi parseInthai lần
Kyle Delaney

4

Theo tôi, công việc có sạch sẽ hơn parseInt không, sử dụng toán tử +

var s = '';
console.log(+s);

var s = '1024'
+s
1024

s = 0
+s
0

s = -1
+s
-1

s = 2.456
+s
2.456

s = ''
+s
0

s = 'wtf'
+s
NaN

1
Rất nhỏ gọn. Thật là xấu hổ khi bạn đã không nhận được nhiều điểm hơn. Tôi đã bình chọn cho bạn lên. Vui lòng đáp lại để cố gắng bắt -2 của tôi có được ngày hôm nay bởi một kẻ troll câm ... (xem câu trả lời của tôi ở cuối trang này). Cảm ơn bạn.
Fabien Haddadi


1

Thực hiện kiểm tra riêng cho một chuỗi trống (vì đây là một trường hợp cụ thể) và đặt nó thành 0 trong trường hợp này.

Bạn có thể xuất hiện "0" khi bắt đầu, nhưng sau đó bạn cần thêm tiền tố để chỉ ra rằng đó là số thập phân chứ không phải số bát phân


Vì vậy, bạn nghĩ tốt hơn là thêm 0 nếu trống?
Joper

1
Không - đó là một cách tiếp cận tôi đã sử dụng. Trong trường hợp này, một kiểm tra riêng biệt sẽ tốt hơn. Tuy nhiên, nếu giải pháp Matts hoạt động, điều đó thậm chí còn sạch hơn.
Schrotingers Cat

1

Tại sao không ghi đè chức năng? Trong trường hợp đó, bạn luôn có thể chắc chắn rằng nó trả về 0trong trường hợp NaN:

(function(original) {
    parseInt = function() {
        return original.apply(window, arguments) || 0;
    };
})(parseInt);

Bây giờ, bất cứ nơi nào trong mã của bạn:

parseInt('') === 0

15
Ghi đè hàm như thế này có thể gây nhầm lẫn cho các lập trình viên JavaScript chuyên gia, những người có thể coi đó là một lỗi. Chức năng bị ghi đè của bạn có khả năng bị chôn vùi ở một nơi không thể nhìn thấy. Đây là sáng tạo, nhưng tôi không chắc chắn cá nhân tôi sẽ khuyên bạn nên xem xét việc thêm một câu || 0như trong câu trả lời của Matt dễ dàng như thế nào . Tôi thấy các đối tượng ghi đè bạn không sở hữu như là phương sách cuối cùng hoặc khi không làm như vậy sẽ có giá cao hơn đáng kể về thời gian và độ phức tạp.
jmort253

2
Tôi đồng ý với @ jmort253 ... Thật nguy hiểm vì chức năng này quá thông minh. Tốt hơn là thực hiện chính xác chức năng tương tự nhưng với một tên như getSafeNumberValue hoặc một cái gì đó tương tự.
Samuel

1

Tôi gặp vấn đề tương tự (firefox v34) với các chuỗi đơn giản như:

var myInt = parseInt("b4");

Vì vậy, tôi đã đưa ra một bản hack nhanh chóng:

var intVal = ("" + val).replace(/[^0-9]/gi, "");

Và sau đó có tất cả sự phức tạp ngu ngốc để đối phó với float + ints cho những thứ không đơn giản:

var myval = "12.34";

function slowParseNumber(val, asInt){
    var ret = Number( ("" + val).replace(/[^0-9\.]/gi, "") );
    return asInt ? Math.floor(ret) : ret;
}
var floatVal = slowParseNumber(myval);

var intVal = slowParseNumber(myval, true);
console.log(floatVal, intVal);

Nó sẽ trả về 0 cho những thứ như:

var intVal = slowParseNumber("b"); // yeilds 0

1
//////////////////////////////////////////////////////
function ToInt(x){x=parseInt(x);return isNaN(x)?0:x;}
//////////////////////////////////////////////////////
var x = ToInt('');   //->  x=0
    x = ToInt('abc') //->  x=0
    x = ToInt('0.1') //->  x=0
    x = ToInt('5.9') //->  x=5
    x = ToInt(5.9)   //->  x=5
    x = ToInt(5)     //->  x=5

Bạn có thể giải thích giải pháp này?
RamenChef

nếu bạn muốn chuyển đổi bất kỳ số nào (như'123 'hoặc 123) thành số nguyên, nếu bạn sẽ sử dụng parseInt (' abc '),
AbdulRahman AlShamiri

nếu bạn sẽ sử dụng parseInt ('abc') thì bạn sẽ chuyển sang NaN nhưng chức năng này sẽ chuyển đổi NaN thành 0
AbdulRahman AlShamiri

Bingo, như là sự thay thế rõ ràng cho ||cách tiếp cận. Tôi biết đây là một câu hỏi và câu trả lời cũ, nhưng câu trả lời này tránh việc gọi parseInt hai lần và sử dụng isNaN một cách chính xác. Nó chỉ cần cơ số parseInt(x, 10)để được kỹ lưỡng. (Sở thích của tôi là một biến nội bộ riêng thay vì sử dụng lại x.)
goodeye

1

Tôi đã tạo một nguyên mẫu 2 để xử lý cái này cho tôi, một cho một số và một cho một Chuỗi.

// This is a safety check to make sure the prototype is not already defined.
Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

// returns the int value or -1 by default if it fails
Number.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

// returns the int value or -1 by default if it fails
String.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

Nếu bạn không muốn sử dụng kiểm tra an toàn, hãy sử dụng

String.prototype.tryParseInt = function(){
    /*Method body here*/
};
Number.prototype.tryParseInt = function(){
     /*Method body here*/
};

Ví dụ sử dụng:

var test = 1;
console.log(test.tryParseInt()); // returns 1

var test2 = '1';
console.log(test2.tryParseInt()); // returns 1

var test3 = '1a';
console.log(test3.tryParseInt()); // returns -1 as that is the default

var test4 = '1a';
console.log(test4.tryParseInt(0));// returns 0, the specified default value

1
// implicit cast
var value = parseInt(tbb*1); // see original question

Giải thích, cho những người không thấy nó tầm thường:

Nhân với một, một phương thức gọi là "diễn viên ngầm", cố gắng biến toán hạng loại không xác định thành kiểu nguyên thủy 'số'. Cụ thể, một chuỗi rỗng sẽ trở thành số 0, biến nó thành một loại đủ điều kiện cho parseInt () ...

Một ví dụ rất hay cũng được đưa ra ở trên bởi PirateApp, người đã đề xuất trả trước dấu +, buộc JavaScript phải sử dụng biểu thức ẩn số.


Đó là một câu trả lời trực tiếp cho câu hỏi ban đầu thân mến của tôi.
Fabien Haddadi

Điều này sẽ không làm choparseInt('str'*1)
Rodion Baskakov

Tại sao gọi parseIntmột cái gì đó đã là một số? Điều đó sẽ phát sinh một chuyển đổi khác trở lại chuỗi chỉ để chuyển đổi lại thành số.
trincot

0

Cũng theo cách này, tại sao không viết một hàm và gọi nó ở bất cứ nơi nào cần thiết. Tôi giả sử đó là mục nhập vào các trường mẫu để thực hiện tính toán.

var Nanprocessor = function (entry) {
    if(entry=="NaN") {
        return 0;
    } else {
        return entry;
    }
}

 outputfield.value = Nanprocessor(x); 

// where x is a value that is collected from a from field
// i.e say x =parseInt(formfield1.value); 

Có gì sai khi làm điều này?


Xin chào, wat dừng chúng tôi theo phương pháp trên. Muốn biết n học.
Naresh

3
Bạn nên sử dụng isNaN để kiểm tra NaN.
Matthew

2
Cảm ơn Matt :) Tôi không biết rằng có một hàm gọi là isNaN () trong javascrip! Cảm ơn vì đã cho tôi biết...!
Naresh

0

Đây là một phương thức tryPudeInt mà tôi đang sử dụng, cái này lấy giá trị mặc định làm tham số thứ hai để nó có thể là bất cứ thứ gì bạn yêu cầu.

function tryParseInt(str, defaultValue) {
    return parseInt(str) == str ? parseInt(str) : defaultValue;
}

tryParseInt("", 0);//0 
tryParseInt("string", 0);//0 
tryParseInt("558", 0);//558

0

một hàm trợ giúp vẫn cho phép sử dụng cơ số

function parseIntWithFallback(s, fallback, radix) {
    var parsed = parseInt(s, radix);
    return isNaN(parsed) ? fallback : parsed;
}

0

Bạn có thể có mã rất sạch, tôi đã gặp vấn đề tương tự và tôi đã giải quyết nó bằng cách sử dụng:

var a="bcd";
~~parseInt(a);

0

Đối với những người khác đang tìm kiếm giải pháp này, chỉ cần sử dụng: ~ ~ không có parseInt, đó là chế độ sạch nhất.

var a = 'hello';
var b = ~~a;

Nếu NaN, nó sẽ trả về 0 thay thế.

OBS. Giải pháp này chỉ áp dụng cho số nguyên

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.