Konversi NaN ke 0 dalam javascript

238

Apakah ada cara untuk mengkonversi nilai NaN ke 0 tanpa pernyataan if:

if (isNaN(a)) a = 0;

Sangat menjengkelkan untuk memeriksa variabel saya setiap saat.

Tamás Pap
sumber
4
Tidak bisakah Anda menyalakannya menjadi sebuah fungsi?
the_drow
Ini hanya seperti 20 karakter, apa masalahnya?
Rusty Fausak
1
function noNaN( n ) { return isNaN( n ) ? 0 : n; }dan kemudiannoNaN( a )
Šime Vidas
1
@ rfausak Anda biasanya tidak ingin mengulang sendiri (lihat KERING ). Jika fungsi tertentu diperlukan beberapa kali, fungsi khusus lebih disukai.
Šime Vidas

Jawaban:

575

Kamu bisa melakukan ini:

a = a || 0

... yang akan mengubah nilai dari "falsey" menjadi 0.

Nilai "falsey" adalah:

  • false
  • null
  • undefined
  • 0
  • "" (string kosong)
  • NaN (Bukan Angka)

Atau ini jika Anda lebih suka:

a = a ? a : 0;

... yang akan memiliki efek yang sama seperti di atas.


Jika maksudnya adalah untuk menguji lebih dari sekadar NaN, maka Anda dapat melakukan hal yang sama, tetapi lakukan konversi toNumber terlebih dahulu.

a = +a || 0

Ini menggunakan operator + unary untuk mencoba mengkonversi ake nomor. Ini memiliki manfaat tambahan untuk mengonversi hal-hal seperti string numerik '123'ke angka.

Satu-satunya hal yang tidak terduga adalah jika seseorang melewati Array yang berhasil dikonversi menjadi nomor:

+['123']  // 123

Di sini kita memiliki Array yang memiliki anggota tunggal yang merupakan string numerik. Ini akan berhasil dikonversi menjadi angka.

pengguna113716
sumber
Gagasan untuk mengubah verifikasi menjadi suatu fungsi memang bagus, tetapi yang ini lebih elegan.
Tamás Pap
1
@ Bakudan: Poin bagus. Saya berpikir OP hanya peduli dengan nilai spesifik NaN. Ini tidak akan berfungsi sebagai tes untuk semua nilai bukan angka. Meskipun kami dapat mencoba konversi toNumber terlebih dahulu. Saya akan memperbarui.
user113716
... ah, itu karena judul "Konversi NaN ke 0" . Pokoknya, dibahas dua arah sekarang.
user113716
2
Terima kasih sobat, telah memilih dan memodifikasi sedikit ini untuk saya sendiri a = a * 1 || 0
Seseorang
Luar biasa. Terima kasih
Apit John Ismail
32

Menggunakan double-tilde (double bitwise NOT) - ~~- melakukan beberapa hal menarik dalam JavaScript. Misalnya Anda dapat menggunakannya sebagai ganti Math.flooratau bahkan sebagai alternatif parseInt("123", 10)! Sudah banyak dibahas di web, jadi saya tidak akan masuk mengapa itu bekerja di sini, tetapi jika Anda tertarik: Apa itu "double tilde" (~~) operator di JavaScript?

Kita dapat mengeksploitasi properti double-tilde ini untuk mengkonversi NaNke angka, dan dengan senang hati angka itu nol!

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

WickyNilliams
sumber
1
Terima kasih, saya tidak tahu tentang hal ini ~~sama sekali, saya hanya menggunakannya sepanjang sisi dengan parseFloat()seperti: ~~parseFloat($variable);. Sangat rapi :) +1
Rens Tillmann
23

Tulis metode Anda sendiri, dan gunakan di mana saja Anda menginginkan nilai angka:

function getNum(val) {
   if (isNaN(val)) {
     return 0;
   }
   return val;
}
Saket
sumber
1
Jika saya lewat nullmaka itu tidak memberi saya hasil yang diharapkan 0. Lebih lanjut tentang poin saya di sini: stackoverflow.com/questions/115548/why-is-isnannull-false-in-js
Andrei Bazanov
2
Lebih jauh ke komentar saya di atas, saya akhirnya menggunakan Number(val)karena itu kembali 0ketika tidak bisa memahaminya.
Andrei Bazanov
4

Sesuatu yang lebih sederhana dan efektif untuk apa pun:

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

... yang akan mengubah nilai dari "falsey" menjadi 0.

Nilai "falsey" adalah:

  • false
  • null
  • undefined
  • 0
  • "" (string kosong)
  • NaN (Bukan Angka)
Woold
sumber
1
Menarik! Hanya ingin tahu bagaimana ini bereaksi ketika val bisa menjadi nilai negatif. Sejauh yang saya uji tidak ada yang salah dengan ini, tetapi untuk berjaga-jaga ...
Luciano
2

Daripada melakukan kludging sehingga Anda bisa melanjutkan, mengapa tidak membuat cadangan dan bertanya-tanya mengapa Anda mengalami NaN?

Jika salah satu input numerik ke operasi adalah NaN, output juga akan menjadi NaN. Begitulah cara standar IEEE Floating Point saat ini (bukan hanya Javascript). Perilaku itu untuk alasan yang baik : niat dasarnya adalah untuk mencegah Anda menggunakan hasil palsu tanpa menyadari itu palsu.

Cara kerja NaN adalah jika terjadi kesalahan pada beberapa sub-sub-operasi (menghasilkan NaN pada level yang lebih rendah), hasil akhirnya juga akan menjadi NaN, yang akan segera Anda kenali sebagai kesalahan walaupun Anda logika penanganan kesalahan (melempar / menangkap mungkin?) belum selesai.

NaN sebagai hasil dari perhitungan aritmatika selalu menunjukkan sesuatu yang serba salah dalam rincian aritmatika. Ini adalah cara bagi komputer untuk mengatakan "diperlukan debug di sini". Alih-alih menemukan cara untuk tetap melanjutkan dengan beberapa nomor yang hampir tidak pernah benar (apakah 0 benar-benar yang Anda inginkan?), Mengapa tidak menemukan masalah dan memperbaikinya.

Masalah umum dalam Javascript adalah bahwa kedua parseInt(...)dan parseFloat(...)akan kembali NaN jika diberi argumen masuk akal ( null, '', dll). Perbaiki masalah di level serendah mungkin daripada di level yang lebih tinggi. Maka hasil perhitungan keseluruhan memiliki peluang bagus untuk masuk akal, dan Anda tidak mengganti beberapa angka ajaib (0 atau 1 atau apa pun) untuk hasil seluruh perhitungan. (Trik (parseInt (foo.value) || 0) hanya berfungsi untuk penjumlahan, bukan produk - untuk produk yang Anda inginkan nilai default menjadi 1 daripada 0, tetapi tidak jika nilai yang ditentukan benar-benar 0.)

Mungkin untuk kemudahan pengkodean Anda ingin fungsi mengambil nilai dari pengguna, membersihkannya, dan memberikan nilai default jika perlu, seperti ini:

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

Bagaimana dengan regex ?

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

Kode di bawah ini akan mengabaikan NaN untuk memungkinkan perhitungan angka yang dimasukkan dengan benar

mplungjan
sumber
2

Metode yang menggunakan isNaN tidak berfungsi jika Anda mencoba menggunakan parseInt, misalnya:

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

Tetapi dalam kasus kedua isNaN menghasilkan false (yaitu string nol adalah angka)

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

Singkatnya, string nol dianggap sebagai nomor yang valid oleh isNaN tetapi tidak oleh parseInt. Diverifikasi dengan Safari, Firefox dan Chrome di OSX Mojave.

David Crowe
sumber
1
Salah satu solusi yang jelas agak rumit, periksa NaN setelah parseInt, bukan sebelumnya: isNaN (parseInt (n))? parseInt (n): 0; // panggilan parseInt dua kali :(
David Crowe
1
komentar itu seharusnya (awal) jawaban Anda!
frandroid
Solusi yang lebih efisien mengasumsikan bahwa string nol adalah satu-satunya anomali: n == "" | | isNaN (n)? 0: parseInt (n); (tetapi bagaimana jika ada string lain?)
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]

KARTHIKEYAN.A
sumber
0

menggunakan solusi pengguna 113716, yang omong-omong sangat bagus untuk menghindari semua itu jika-kalau tidak saya telah menerapkannya dengan cara ini untuk menghitung kotak teks subtotal saya dari unit kotak teks dan jumlah kotak teks.

Dalam proses penulisan angka non dalam kotak teks kuantitas dan satuan, nilainya diganti dengan nol sehingga posting akhir data pengguna tidak memiliki angka.

     <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"/>
webzy
sumber
0

Silakan coba fungsi sederhana ini

var NanValue = function (entry) {
    if(entry=="NaN") {
        return 0.00;
    } else {
        return entry;
    }
}
subindas pm
sumber