Chuyển đổi NaN thành 0 trong javascript


238

Có cách nào để chuyển đổi giá trị NaN thành 0 mà không có câu lệnh if:

if (isNaN(a)) a = 0;

Nó rất khó chịu để kiểm tra các biến của tôi mỗi lần.


4
Bạn có thể ném nó thành một chức năng không?
the_drow

Điều này chỉ giống như 20 ký tự, vấn đề là gì?
Rusty Fausak

1
function noNaN( n ) { return isNaN( n ) ? 0 : n; }và sau đó chỉ lànoNaN( a )
Vidime Vidas

1
@rfausak Bạn thường không muốn lặp lại chính mình (xem DRY ). Nếu một chức năng nhất định là cần thiết nhiều lần, một chức năng chuyên dụng được ưu tiên.
Vidime Vidas

Câu trả lời:


574

Bạn có thể làm được việc này:

a = a || 0

... sẽ chuyển đổi từ bất kỳ giá trị "falsey" nào 0.

Các giá trị "falsey" là:

  • false
  • null
  • undefined
  • 0
  • "" (chuỗi trống)
  • NaN ( Không phải là một con số )

Hoặc điều này nếu bạn thích:

a = a ? a : 0;

... sẽ có tác dụng tương tự như trên.


Nếu mục đích là để kiểm tra nhiều hơn chỉ NaN, thì bạn có thể làm tương tự, nhưng trước tiên hãy thực hiện chuyển đổi toNumber .

a = +a || 0

Điều này sử dụng toán tử unary + để cố gắng chuyển đổi athành một số. Điều này có thêm lợi ích của việc chuyển đổi những thứ như chuỗi '123'số thành số.

Điều bất ngờ duy nhất có thể là nếu ai đó vượt qua một mảng có thể được chuyển đổi thành số thành công:

+['123']  // 123

Ở đây chúng ta có một Mảng có một thành viên là một chuỗi số. Nó sẽ được chuyển đổi thành một số.


Ý tưởng để biến xác minh thành một chức năng là tốt, nhưng điều này là thanh lịch hơn.
Tamás Pap

1
@Bakudan: Điểm tốt. Tôi đã nghĩ OP chỉ quan tâm đến NaNgiá trị cụ thể . Điều này sẽ không hoạt động như một thử nghiệm cho tất cả các giá trị không số. Mặc dù chúng tôi có thể thử chuyển đổi toNumber trước. Tôi sẽ cập nhật.
dùng113716

... ah, đó là vì tiêu đề "Chuyển đổi NaN thành 0" . Dù sao, bao phủ cả hai cách bây giờ.
dùng113716

2
Cảm ơn bạn, đã chọn và sửa đổi một chút điều này cho bản thân mình a = a * 1 || 0
Ai đó

Tuyệt vời. Cảm ơn
Apit John Ismail

32

Sử dụng dấu ngã đôi (gấp đôi bitwise KHÔNG) - ~~- thực hiện một số điều thú vị trong JavaScript. Chẳng hạn, bạn có thể sử dụng nó thay vì Math.floorhoặc thậm chí thay thế parseInt("123", 10)! Nó đã được thảo luận rất nhiều trên web, vì vậy tôi sẽ không tìm hiểu lý do tại sao nó hoạt động ở đây, nhưng nếu bạn quan tâm: Toán tử "dấu ngã kép" (~ ~) trong JavaScript là gì?

Chúng ta có thể khai thác thuộc tính này của một dấu ngã kép để chuyển đổi NaNthành một số và rất vui khi số đó bằng không!

console.log(~~NaN); // 0


1
Cảm ơn, tôi hoàn toàn không biết về điều này ~~, tôi chỉ sử dụng nó cùng với parseFloat()như vậy : ~~parseFloat($variable);. Rất gọn gàng :) +1
Rens Tillmann

23

Viết phương thức của riêng bạn và sử dụng nó ở mọi nơi bạn muốn có một giá trị số:

function getNum(val) {
   if (isNaN(val)) {
     return 0;
   }
   return val;
}

1
Nếu tôi vượt qua nullthì nó không cho tôi kết quả như mong đợi 0. Thông tin thêm về quan điểm của tôi ở đây: stackoverflow.com/questions/115548/why-is-isnannull-false-in-js
Andrei Bazanov 15/03/17

2
Hơn nữa với nhận xét của tôi ở trên, tôi đã kết thúc bằng cách sử dụng Number(val)thay vì nó trở lại 0khi nó không thể tìm ra bằng cách nào.
Andrei Bazanov

4

Một cái gì đó đơn giản và hiệu quả cho mọi thứ:

function getNum(val) {
   val = +val || 0
   return val;
}

... sẽ chuyển đổi từ bất kỳ giá trị "falsey" nào 0.

Các giá trị "falsey" là:

  • false
  • null
  • undefined
  • 0
  • "" (chuỗi trống)
  • NaN ( Không phải là một con số )

1
Hấp dẫn! Chỉ tự hỏi làm thế nào nó phản ứng khi val có thể là một giá trị âm. Theo như tôi đã thử nghiệm thì không có gì sai với điều này, nhưng chỉ trong trường hợp ...
Luciano

2

Thay vì loại bỏ nó để bạn có thể tiếp tục, tại sao không sao lưu và tự hỏi tại sao bạn lại chạy vào NaN ngay từ đầu?

Nếu bất kỳ đầu vào số nào cho một hoạt động là NaN, đầu ra cũng sẽ là NaN. Đó là cách mà tiêu chuẩn IEEE Floating Point hiện tại hoạt động (nó không chỉ là Javascript). Hành vi đó là vì một lý do chính đáng : mục đích cơ bản là ngăn bạn sử dụng kết quả không có thật mà không nhận ra đó là không có thật.

Cách thức hoạt động của NaN là nếu có sự cố xảy ra trong một số hoạt động phụ phụ (tạo ra NaN ở cấp độ thấp hơn), kết quả cuối cùng cũng sẽ là NaN, ngay lập tức bạn sẽ nhận ra đó là lỗi ngay cả khi logic xử lý lỗi (có thể ném / bắt?) chưa hoàn tất.

NaN là kết quả của một phép tính số học luôn chỉ ra điều gì đó đã bị sai lệch trong các chi tiết của số học. Đó là một cách để máy tính nói "gỡ lỗi cần thiết ở đây". Thay vì tìm cách nào đó để tiếp tục với bất kỳ số nào hầu như không bao giờ đúng (là 0 thực sự là những gì bạn muốn?), Tại sao không tìm ra vấn đề và khắc phục nó.

Một vấn đề thường gặp trong Javascript là cả hai parseInt(...)parseFloat(...)sẽ trở lại NaN nếu có một cuộc tranh luận vô nghĩa ( null, '', vv). Khắc phục sự cố ở mức thấp nhất có thể thay vì ở cấp cao hơn. Sau đó, kết quả của phép tính tổng thể có cơ hội tốt và bạn không thay thế một số số ma thuật (0 hoặc 1 hoặc bất cứ điều gì) cho kết quả của toàn bộ phép tính. (Thủ thuật của (parseInt (foo.value) || 0) chỉ hoạt động đối với các khoản tiền, không phải sản phẩm - đối với các sản phẩm bạn muốn giá trị mặc định là 1 chứ không phải 0, nhưng không phải nếu giá trị được chỉ định thực sự là 0.)

Có lẽ để dễ mã hóa, bạn muốn một hàm lấy một giá trị từ người dùng, dọn sạch nó và cung cấp một giá trị mặc định nếu cần, như thế này:

function getFoobarFromUser(elementid) {
        var foobar = parseFloat(document.getElementById(elementid).innerHTML)
        if (isNaN(foobar)) foobar = 3.21;       // default value
        return(foobar.toFixed(2));
}

2

Làm thế nào về một regex ?

function getNum(str) {
  return /[-+]?[0-9]*\.?[0-9]+/.test(str)?parseFloat(str):0;
}

Mã dưới đây sẽ bỏ qua NaN để cho phép tính các số được nhập đúng


2

Các phương thức sử dụng isNaN không hoạt động nếu bạn đang cố sử dụng parseInt, ví dụ:

parseInt("abc"); // NaN
parseInt(""); // NaN
parseInt("14px"); // 14

Nhưng trong trường hợp thứ hai, isNaN tạo false (tức là chuỗi null là một số)

n="abc"; isNaN(n) ? 0 : parseInt(n); // 0
n=""; isNaN(n) ? 0: parseInt(n); // NaN
n="14px"; isNaN(n) ? 0 : parseInt(n); // 14

Tóm lại, chuỗi null được coi là một số hợp lệ bởi isNaN nhưng không phải bởi parseInt. Được xác minh bằng Safari, Firefox và Chrome trên OSX Mojave.


1
Một giải pháp rõ ràng là hơi cồng kềnh, hãy kiểm tra NaN sau parseInt, không phải trước: isNaN (parseInt (n))? phân tích (n): 0; // gọi parseInt hai lần :(
David Crowe

1
bình luận đó nên là (sự khởi đầu) câu trả lời của bạn!
frandroid

Một giải pháp hiệu quả hơn giả định rằng chuỗi null là sự bất thường duy nhất: n == "" | | isNaN (n)? 0: phân tích (n); (nhưng nếu có các chuỗi khác thì sao?)
David Crowe

1
var i = [NaN, 1,2,3];

var j = i.map(i =>{ return isNaN(i) ? 0 : i});

console.log(j)

[0,1,2,3]


0

bằng cách sử dụng giải pháp 113716 của người dùng, điều này thật tuyệt vời để tránh tất cả những điều đó nếu tôi đã thực hiện theo cách này để tính toán hộp văn bản phụ của tôi từ đơn vị hộp văn bản và số lượng hộp văn bản.

Trong quá trình viết các số không trong các hộp văn bản đơn vị và số lượng, các giá trị của chúng được thay thế bằng 0 để việc đăng dữ liệu người dùng cuối cùng không có số không.

     <script src="/common/tools/jquery-1.10.2.js"></script>
     <script src="/common/tools/jquery-ui.js"></script>

     <!----------------- link above 2 lines to your jquery files ------>





    <script type="text/javascript" >
    function calculate_subtotal(){

    $('#quantity').val((+$('#quantity').val() || 0));
    $('#unit').val((+$('#unit').val() || 0));

    var  calculated = $('#quantity').val() * $('#unit').val() ;
    $('#subtotal').val(calculated);


    }
    </script>


      <input type = "text" onChange ="calculate_subtotal();" id = "quantity"/>
      <input type = "text" onChange ="calculate_subtotal();" id = "unit"/>
      <input type = "text" id = "subtotal"/>

0

Hãy thử chức năng đơn giản này

var NanValue = function (entry) {
    if(entry=="NaN") {
        return 0.00;
    } else {
        return entry;
    }
}
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.