JavaScript tidak berlaku

170

Saya menemukan kode berikut:

function test(data) {
    if (data != null && data !== undefined) {
        // some code here
    }
}

Saya agak baru mengenal JavaScript, tetapi, dari pertanyaan lain yang saya baca di sini, saya mendapat kesan bahwa kode ini tidak masuk akal.


Secara khusus, jawaban ini menyatakan itu

Anda akan mendapatkan kesalahan jika Anda mengakses variabel yang tidak ditentukan dalam konteks apa pun selain typeof.

Pembaruan: Jawaban (kutipan) di atas mungkin menyesatkan. Itu harus mengatakan «variabel yang tidak dideklarasikan» , alih-alih «variabel yang tidak ditentukan» .

Seperti yang saya temukan, dalam jawaban oleh Ryan ♦ , maerics , dan nwellnhof , bahkan ketika tidak ada argumen yang disediakan untuk suatu fungsi, variabelnya untuk argumen selalu dideklarasikan. Fakta ini juga membuktikan salah item pertama dalam daftar di bawah ini.


Dari pemahaman saya, skenario berikut mungkin dialami:

  • Fungsi dipanggil tanpa argumen, sehingga membuat datavariabel tidak terdefinisi, dan meningkatkan kesalahan data != null.

  • Fungsi dipanggil secara khusus dengan null(atau undefined), sebagai argumennya, dalam hal ini data != nullsudah melindungi kode bagian dalam, menjadikannya && data !== undefinedtidak berguna.

  • Fungsi dipanggil dengan argumen non-nol, dalam hal ini akan melewati keduanya data != null dan data !== undefined .

T: Apakah pemahaman saya benar?


Saya sudah mencoba yang berikut ini, di konsol Firefox:

--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true

Saya tidak bisa menemukan kasus di mana data !== undefined setelahnya data != null mungkin ada gunanya.

afsantos
sumber
9
Gunakan saja if (data). Ini adalah cara Javascript mnemonic untuk memeriksa apakah datavariabel bernilai true. undefined,, nullfalse, 0, string kosong, array kosong, dan (?) objek tanpa properti bernilai false, sisanya benar.
J0HN
20
@ J0HN - Menggunakan if(data)berarti dia tidak bisa lulus falseatau 0sebagai nilai untuk data.
techfoobar
@ J0HN Juga, jawaban yang sama yang saya sebutkan juga menyatakan bahwa:, if(typeof someUndefVar == whatever) -- worksdan if(someUnderVar) -- error.
afsantos
2
Mungkin seharusnya data !== null && data !== undefined, yang setara dengan data != nullyang setara dengan data != undefined. Bentuk sebelumnya cenderung disukai karena lebih eksplisit tentang kondisi, sedangkan akan mudah untuk mengabaikan keduanya nulldan undefinedsedang diperiksa dengan dua kondisi selanjutnya.
zzzzBov
2
Omong-omong, tes eksplisit untuk undefinedIMO adalah bau kode. Ini bukan kata kunci yang dilindungi seperti null, ini adalah variabel yang tidak terdefinisi. Ini benar-benar valid dan akan memecahkan kode Anda:undefined = 1
Izkata

Jawaban:

106

“Variabel tidak terdefinisi” berbeda dari nilainya undefined.

Variabel tidak terdefinisi:

var a;
alert(b); // ReferenceError: b is not defined

Variabel dengan nilai undefined:

var a;
alert(a); // Alerts “undefined”

Ketika suatu fungsi mengambil argumen, argumen itu selalu dideklarasikan meskipun nilainya demikian undefined, sehingga tidak akan ada kesalahan. Anda benar tentang != nulldiikuti oleh !== undefinedmenjadi tidak berguna.

Ry-
sumber
32
data !== null && data !== undefinedakan masuk akal.
bfavaretto
@ bfavaretto: Ya, jadi itu mungkin salah ketik. Tapi Anda tidak pernah tahu ...: D
Ry-
1
Sama seperti yang saya pikirkan, terima kasih atas klarifikasi. Juga, saya tidak berpikir itu salah ketik. Saya telah menjalankan pencarian-dan-hitung di seluruh skrip, dan ia menemukan 10 kejadian, jadi ... Saya kira penulis juga perlu klarifikasi tentang ini.
afsantos
2
Gores komentar saya di atas: sebenarnya, data != nullakan memeriksa keduanya nulldan undefined(tapi, yang menarik, hanya untuk nulldan undefined, dan bukan nilai-nilai palsu lainnya).
bfavaretto
90

Dalam JavaScript, nulladalah objek tunggal khusus yang berguna untuk memberi sinyal "tidak ada nilai". Anda dapat mengujinya dengan perbandingan dan, seperti biasa dalam JavaScript, praktik yang baik untuk menggunakan ===operator untuk menghindari paksaan jenis yang membingungkan:

var a = null;
alert(a === null); // true

Seperti @rynah menyebutkan, "undefined" agak membingungkan dalam JavaScript. Namun, selalu aman untuk menguji apakah typeof(x)string "tidak terdefinisi", bahkan jika "x" bukan variabel yang dideklarasikan:

alert(typeof(x) === 'undefined'); // true

Selain itu, variabel dapat memiliki "nilai tidak terdefinisi" jika tidak diinisialisasi:

var y;
alert(typeof(y) === 'undefined'); // true

Menyatukan semuanya, cek Anda akan terlihat seperti ini:

if ((typeof(data) !== 'undefined') && (data !== null)) {
  // ...

Namun, karena variabel "data" selalu ditentukan karena ini adalah parameter fungsi formal, menggunakan operator "typeof" tidak diperlukan dan Anda dapat dengan aman membandingkan langsung dengan "nilai yang tidak ditentukan".

function(data) {
  if ((data !== undefined) && (data !== null)) {
    // ...

Cuplikan ini sama dengan mengatakan "jika fungsi dipanggil dengan argumen yang didefinisikan dan bukan nol ..."

maerics
sumber
5
Kenapa harus terlihat seperti itu? != nullakan berlaku untuk semua nilai kecuali nulldan undefined, dan kami yakin bahwa variabel ini dideklarasikan. typeofdalam situasi lain bahkan bisa berbahaya - bagaimana jika Anda salah ketik nama variabel? Itu bisa tidak terdeteksi untuk waktu yang lama karena tidak ada kesalahan.
Ry-
@maerics Jadi, jika saya mengikuti jawaban Anda dengan benar, dalam cek nol seperti skenario di atas, Anda tidak akan menggunakan !=sama sekali, hanya perbandingan ketat !==,?
afsantos
@rynah: Saya tidak berasumsi cukup tahu tentang solusi keseluruhan OP untuk mengetahui apakah tes nol sesuai atau tidak, tetapi saya mengedit untuk menyebutkan fakta bahwa menggunakan "typeof" tidak perlu.
maerics
@afsantos: pada kenyataannya saya tidak berpikir bahwa banyak (ada?) nilai akan dikonversi menjadi nol; namun, ini adalah praktik terbaik untuk menggunakan perbandingan ketat ( ===) kecuali Anda benar-benar tahu apa yang Anda lakukan dan ingin perbandingan setelah konversi ( ==).
maerics
1
@Izkata: Jatuhkan perpustakaan apa pun yang mencoba mendefinisikan ulang undefined. Juga, Safari di iPad akan melakukan itu dalam keadaan apa pun. Anda bahkan tidak bisa delete window.undefined.
Ry-
10

Dalam kasus Anda gunakan data==null(yang HANYA berlaku untuk null dan tidak terdefinisi - pada fokus gambar kedua pada baris / kolom null-undefined)

Di sini Anda memiliki semua ( src ):

jika

masukkan deskripsi gambar di sini

== (negasinya ! = )

masukkan deskripsi gambar di sini

=== (negasinya ! == )

masukkan deskripsi gambar di sini

Kamil Kiełczewski
sumber
8

Q: Fungsi dipanggil tanpa argumen, sehingga menjadikan data sebagai variabel yang tidak terdefinisi, dan meningkatkan kesalahan pada data! = Null.

A: Ya, dataakan ditetapkan ke tidak terdefinisi. Lihat bagian 10.5 Instansiasi Pengikatan Deklarasi dari spec. Tetapi mengakses nilai yang tidak ditentukan tidak menimbulkan kesalahan. Anda mungkin membingungkan ini dengan mengakses variabel yang tidak dideklarasikan dalam mode ketat yang memang memunculkan kesalahan.

Q: Fungsi dipanggil secara khusus dengan null (atau tidak terdefinisi), sebagai argumennya, dalam hal ini data! = Null sudah melindungi kode bagian dalam, membuat && data! == tidak terdefinisi sia-sia.

Q: Fungsi ini dipanggil dengan argumen non-nol, yang dalam hal ini sepele akan melewatkan kedua data! = Null dan data! == tidak terdefinisi.

A: Benar. Perhatikan bahwa tes berikut ini setara:

data != null
data != undefined
data !== null && data !== undefined

Lihat bagian 11.9.3 Algoritma Perbandingan Kesetaraan Abstrak dan bagian 11.9.6 Algoritma Perbandingan Kesetaraan Ketat dari spesifikasi.

nwellnhof
sumber
Saya tidak bingung dengan variabel yang tidak dideklarasikan, saya benar-benar tidak tahu cara kerjanya ketika tidak ada argumen yang diberikan. Saya yakin itu datatidak akan ada sama sekali, bukannya ditetapkan undefined. Saya menghargai klarifikasi, dan referensi itu membantu saya memahami dengan lebih baik bagaimana kedua persamaan bekerja.
afsantos
3

Saya pikir, menguji variabel untuk nilai yang tidak Anda harapkan bukanlah ide yang baik secara umum. Karena ujian sebagai Anda, Anda dapat mempertimbangkan sebagai menulis daftar hitam dari nilai-nilai terlarang. Tetapi bagaimana jika Anda lupa membuat daftar semua nilai terlarang? Seseorang, bahkan Anda, dapat memecahkan kode Anda dengan memberikan nilai yang tidak terduga. Jadi pendekatan yang lebih tepat adalah sesuatu seperti daftar putih - menguji variabel hanya untuk nilai yang diharapkan, bukan yang tidak terduga. Misalnya, jika Anda mengharapkan nilai data menjadi string, alih-alih ini:

function (data) {
  if (data != null && data !== undefined) {
    // some code here
    // but what if data === false?
    // or data === '' - empty string?
  }
}

lakukan sesuatu seperti ini:

function (data) {
  if (typeof data === 'string' && data.length) {
    // consume string here, it is here for sure
    // cleaner, it is obvious what type you expect
    // safer, less error prone due to implicit coercion
  } 
}

sumber
2

typeof foo === "undefined"berbeda dari foo === undefined, tidak pernah membingungkan mereka. typeof foo === "undefined"adalah apa yang benar-benar Anda butuhkan. Juga, gunakan !==di tempat!=

Jadi pernyataan itu bisa ditulis sebagai

function (data) {
  if (typeof data !== "undefined" && data !== null) {
    // some code here
  }
}

Edit:

Anda tidak dapat menggunakan foo === undefineduntuk variabel yang tidak dideklarasikan.

var t1;

if(typeof t1 === "undefined")
{
  alert("cp1");
}

if(t1 === undefined)
{
  alert("cp2");
}

if(typeof t2 === "undefined")
{
  alert("cp3");
}

if(t2 === undefined) // fails as t2 is never declared
{
  alert("cp4");
}

sumber
1
Oke, tetapi variabelnya dideklarasikan dalam kasus ini, jadi apa masalahnya?
Ry-
Secara pribadi, saya merasa foo === undefinedberbahaya untuk digunakan. Itu membuat kode Anda gagal untuk kondisi yang sama dengan yang Anda coba cegah.
Saya sedang berbicara tentang argumen ke fungsi yang dimaksud. Lihat juga komentar saya yang lain .
Ry-
1
Mengapa ini diturunkan? Kalimat pertama adalah perbedaan yang benar dan penting !
Izkata
1
@Izkata: karena tidak ada penjelasan untuk pernyataan awal. foo === undefinedsangat dapat diterima dalam situasi OP (dengan asumsi undefinedbelum diganti). Jawabannya juga gagal menjelaskan mengapa !== harus digunakan sebagai pengganti !=.
Matt
1

Cara sederhana untuk melakukan tes Anda adalah:

function (data) {
    if (data) { // check if null, undefined, empty ...
        // some code here
    }
}
Kadiri
sumber
5
Bukankah ini tergantung pada konteks tes? Maksud saya, jika tipe yang diharapkan untuk datastring, tes ini mengembalikan false pada string kosong, yang mungkin, atau mungkin tidak, sesuai (fungsi mungkin ingin berurusan dengan string kosong dalam beberapa cara).
afsantos
5
Kecuali bahwa jika "data" memiliki nilai ""atau 0atau NaN(atau yang lain) blok "jika" akan dilewati; yang mungkin atau tidak mungkin niat OP.
maerics
Maaf @afsantos, saya tidak melihat komentar Anda, jika Anda ingin mendapatkan salah ketika data tidak terdefinisi, nol ... kecuali ketika tanggal kosong, Anda harus membuat var toTest = data; dengan tes lain setelah yang pertama seperti: if (toTest == "") {// beberapa kode di sini}
Kadiri
-5
var a;
alert(a); //Value is undefined

var b = "Volvo"; 
alert(b); //Value is Volvo

var c = null;
alert(c); //Value is null
meluap
sumber
4
Harap tambahkan beberapa penjelasan tentang apa artinya ini.
Ry-
Ini tidak benar-benar memeriksa untuk null.
user4642212