Mendeteksi properti objek yang tidak terdefinisi

2841

Apa cara terbaik untuk memeriksa apakah properti objek dalam JavaScript adalah undefined?

Matt Sheppard
sumber

Jawaban:

2681

Cara biasa untuk memeriksa apakah nilai properti adalah nilai spesial undefined, adalah:

if(o.myProperty === undefined) {
  alert("myProperty value is the special value `undefined`");
}

Untuk memeriksa apakah suatu objek tidak benar-benar memiliki properti seperti itu, dan karena itu akan kembali undefinedsecara default ketika Anda mencoba dan mengaksesnya:

if(!o.hasOwnProperty('myProperty')) {
  alert("myProperty does not exist");
}

Untuk memeriksa apakah nilai yang terkait dengan pengidentifikasi adalah nilai khusus undefined, atau jika pengidentifikasi tersebut belum dinyatakan. Catatan: metode ini adalah satu-satunya cara merujuk ke pengidentifikasi yang tidak dideklarasikan (note: berbeda dengan memiliki nilai undefined) tanpa kesalahan awal:

if(typeof myVariable === 'undefined') {
  alert('myVariable is either the special value `undefined`, or it has not been declared');
}

Dalam versi JavaScript sebelum ECMAScript 5, properti bernama "tidak terdefinisi" pada objek global dapat ditulisi, dan oleh karena itu pemeriksaan sederhana foo === undefinedmungkin berperilaku tidak terduga jika secara tidak sengaja telah didefinisikan ulang. Dalam JavaScript modern, properti ini hanya baca.

Namun, dalam JavaScript modern, "tidak terdefinisi" bukan kata kunci, sehingga variabel di dalam fungsi dapat dinamai "tidak terdefinisi" dan membayangi properti global.

Jika Anda khawatir tentang kasing tepi (tidak mungkin) ini, Anda dapat menggunakan operator void untuk mendapatkan nilai spesial undefineditu sendiri:

if(myVariable === void 0) {
  alert("myVariable is the special value `undefined`");
}
Ry-
sumber
9
jika ada sesuatu yang null maka itu didefinisikan (sebagai nol), tetapi Anda bisa mengkonjugasikan cek juga. Detail yang menyebalkan dari kode di atas adalah bahwa Anda tidak dapat mendefinisikan fungsi untuk memeriksanya, yah Anda dapat mendefinisikan fungsi ... tetapi cobalah untuk menggunakannya.
neu-rah
5
@ neu-rah kenapa kamu tidak bisa menulis fungsi? mengapa sesuatu seperti ini tidak berfungsi? Tampaknya bekerja untuk saya. Apakah ada kasus yang tidak saya pertimbangkan? jsfiddle.net/djH9N/6
Zack
7
@Zack Tes Anda untuk isNullorUndefined tidak mempertimbangkan kasus di mana Anda memanggil isNullOrUndefined (f) dan f tidak dideklarasikan (yaitu di mana tidak ada deklarasi "var f").
pnkfelix
109
Blah, ribuan suara sekarang. Ini adalah cara terburuk yang mungkin dilakukan. Saya harap orang yang lewat melihat komentar ini dan memutuskan untuk memeriksa ... ahem ... jawaban lain .
Ry-
17
Anda bisa menggunakannya obj !== undefinedsekarang. undefineddulu bisa berubah, seperti undefined = 1234apa yang akan menyebabkan hasil yang menarik. Tetapi setelah Ecmascript 5, itu tidak bisa ditulisi lagi, jadi kita bisa menggunakan versi yang lebih sederhana. codereadability.com/how-to-check-for-undefined-in-javascript
Bruno Buccolo
899

Saya percaya ada sejumlah jawaban yang salah untuk topik ini. Bertentangan dengan kepercayaan umum, "tidak terdefinisi" bukanlah kata kunci dalam JavaScript dan sebenarnya dapat memiliki nilai yang ditetapkan untuk itu.

Kode yang benar

Cara paling kuat untuk melakukan tes ini adalah:

if (typeof myVar === "undefined")

Ini akan selalu mengembalikan hasil yang benar, dan bahkan menangani situasi di mana myVartidak dinyatakan.

Kode degenerasi. JANGAN GUNAKAN.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Selain itu, myVar === undefinedakan memunculkan kesalahan dalam situasi di mana myVar tidak dideklarasikan.

MarkPflug
sumber
133
+1 karena mencatat bahwa myVar === tidak terdefinisi akan memunculkan kesalahan jika myVar tidak dideklarasikan
Enrique
73
Saya menemukan pembenaran pertama yang diberikan di sini untuk tidak menggunakan === undefinedmembingungkan. Ya, Anda dapat menetapkan undefined, tetapi tidak ada alasan yang sah untuk melakukannya, dan dapat diprediksi bahwa hal itu dapat merusak kode Anda. Dalam C Anda bisa #define true false, dan dengan Python Anda dapat menetapkan untuk Truedan False, tetapi orang tidak merasa perlu untuk merancang kode mereka dalam bahasa-bahasa tersebut sedemikian rupa untuk melindungi terhadap kemungkinan diri mereka dengan sengaja menyabot lingkungan mereka sendiri di tempat lain dalam kode . Mengapa kemungkinan penugasan undefinedbahkan layak dipertimbangkan di sini?
Mark Amery
19
selain komentar Marks, saya tidak mendapatkan ini: "myVar === tidak terdefinisi akan meningkatkan kesalahan dalam situasi di mana myVar tidak dideklarasikan." - mengapa ini buruk? Mengapa saya tidak ingin memiliki kesalahan jika saya mereferensikan variabel yang tidak dideklarasikan?
eis
5
Juga perlu diingat bahwa Anda selalu dapat melakukan void 0untuk mendapatkan nilai yang undefinedmenunjuk. Jadi kamu bisa melakukannya if (myVar === void 0). yang 0tidak spesial, Anda benar-benar dapat menempatkan ekspresi apa pun di sana.
Claudiu
28
Di peramban modern (FF4 +, IE9 +, Chrome tidak diketahui), tidak mungkin lagi dimodifikasi undefined. MDN: tidak terdefinisi
user247702
228

Meskipun direkomendasikan dengan keras oleh banyak jawaban lain di sini, typeof adalah pilihan yang buruk . Itu tidak boleh digunakan untuk memeriksa apakah variabel memiliki nilai undefined, karena itu bertindak sebagai cek gabungan untuk nilai undefineddan untuk apakah suatu variabel ada. Dalam sebagian besar kasus, Anda tahu kapan variabel ada, dan typeofhanya akan memperkenalkan potensi kegagalan diam jika Anda membuat kesalahan ketik pada nama variabel atau dalam string literal 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

Jadi, kecuali Anda melakukan deteksi fitur², di mana ada ketidakpastian apakah nama yang diberikan akan berada dalam lingkup (seperti memeriksa typeof module !== 'undefined'sebagai langkah dalam kode khusus untuk lingkungan CommonJS), typeofadalah pilihan yang berbahaya ketika digunakan pada variabel, dan opsi yang benar adalah untuk membandingkan nilai secara langsung:

var foo = …;

if (foo === undefined) {
    
}

Beberapa kesalahpahaman umum tentang ini termasuk:

  • bahwa membaca variabel "tidak diinisialisasi" ( var foo) atau parameter ( function bar(foo) { … }, disebut sebagai bar()) akan gagal. Ini tidak benar - variabel tanpa inisialisasi eksplisit dan parameter yang tidak diberi nilai selalu menjadi undefined, dan selalu dalam cakupan.

  • yang undefinedbisa ditimpa. Ada banyak lagi untuk ini. undefinedbukan kata kunci dalam JavaScript. Alih-alih, ini adalah properti pada objek global dengan nilai Undefined. Namun, sejak ES5, properti ini hanya-baca dan tidak dapat dikonfigurasi . Tidak ada peramban modern yang memungkinkan undefinedproperti diubah, dan pada 2017 ini sudah lama terjadi. Kurangnya mode ketat juga tidak memengaruhi undefinedperilaku - itu hanya membuat pernyataan seperti undefined = 5tidak melakukan apa pun alih-alih melempar. Karena itu bukan kata kunci, Anda dapat mendeklarasikan variabel dengan nama undefined, dan variabel-variabel itu dapat diubah, membuat pola yang dulu umum ini:

    (function (undefined) {
        // …
    })()

    lebih berbahaya daripada menggunakan global undefined. Jika Anda harus kompatibel undefineddengan ES3, ganti dengan void 0- jangan gunakan typeof. ( voidselalu menjadi operator unary yang mengevaluasi nilai Undefined untuk setiap operan.)

Dengan cara variabel bekerja, saatnya untuk menjawab pertanyaan aktual: properti objek. Tidak ada alasan untuk menggunakan typeofproperti objek. Pengecualian sebelumnya tentang deteksi fitur tidak berlaku di sini - typeofhanya memiliki perilaku khusus pada variabel, dan ekspresi bahwa properti objek referensi bukan variabel.

Ini:

if (typeof foo.bar === 'undefined') {
    
}

adalah selalu persis sama ke this³:

if (foo.bar === undefined) {
    
}

dan dengan mempertimbangkan saran di atas, untuk menghindari pembaca yang bingung tentang mengapa Anda menggunakan typeof, karena itu paling masuk akal ===untuk memeriksa kesetaraan, karena bisa direactored untuk memeriksa nilai variabel nanti, dan karena itu hanya sekadar terlihat lebih baik, Anda harus selalu menggunakan === undefined³ di sini juga .

Hal lain yang perlu dipertimbangkan ketika datang ke properti objek adalah apakah Anda benar-benar ingin memeriksa undefinedsama sekali. Nama properti yang diberikan dapat tidak ada pada objek (menghasilkan nilai undefinedsaat membaca), hadir pada objek itu sendiri dengan nilai undefined, hadir pada prototipe objek dengan nilai undefined, atau hadir pada salah satu dari mereka yang tidak undefinedbernilai. 'key' in objakan memberi tahu Anda apakah kunci ada di mana saja di rantai prototipe objek, dan Object.prototype.hasOwnProperty.call(obj, 'key')akan memberi tahu Anda apakah itu langsung di objek. Saya tidak akan menjelaskan secara terperinci dalam jawaban ini tentang prototipe dan menggunakan benda-benda sebagai peta kunci-string, karena itu sebagian besar dimaksudkan untuk melawan semua saran buruk dalam jawaban lain terlepas dari kemungkinan interpretasi dari pertanyaan asli. Baca terusobjek prototipe di MDN untuk lebih!

¹ pilihan contoh nama variabel yang tidak biasa? ini kode mati asli dari ekstensi NoScript untuk Firefox.
² jangan berasumsi bahwa tidak mengetahui apa yang ada dalam ruang lingkup secara umum, oke. kerentanan bonus yang disebabkan oleh penyalahgunaan ruang lingkup dinamis: Project Zero 1225
³ sekali lagi mengasumsikan lingkungan ES5 + dan yang undefinedmengacu pada undefinedproperti objek global. gantikan void 0sebaliknya.

Ry-
sumber
@BenjaminGruenbaum Benar tapi benar-benar menyesatkan. Setiap konteks non-standar dapat menentukan sendiri undefined, menyembunyikan yang default. Yang untuk tujuan paling praktis memiliki efek yang sama dengan menimpanya.
blgt
23
@blgt Itu paranoid dan tidak relevan untuk hal praktis. Setiap konteks dapat mengesampingkan console.log, mendefinisikan kembali metode prototipe Array, dan bahkan mengesampingkan Function.prototype.call` hooking, dan mengubah setiap kali Anda memanggil fungsi dalam JavaScript. Melindungi dari ini sangat paranoid dan agak konyol. Seperti yang saya (dan minitech) katakan, Anda bisa gunakan void 0untuk membandingkan dengan yang tidak ditentukan tapi sekali lagi - itu konyol dan berlebihan.
Benjamin Gruenbaum
19
Saya berharap saya memiliki lebih dari satu suara untuk diberikan. Ini jawaban yang paling benar. Saya benar-benar ingin berhenti melihat typeof something === "undefined") kode.
Simon Baumgardt-Wellander
@BenjaminGruenbaum Untuk programmer yang malas, void 0(untuk sekali) keduanya lebih pendek dan lebih aman! Itu kemenangan dalam buku saya.
wizzwizz4
4
Ini benar-benar harus menjadi jawaban yang diterima. Ini adalah yang paling teliti dan terkini.
Patrick Michaelsen
161

Dalam JavaScript ada null dan ada undefined . Mereka memiliki arti yang berbeda.

  • undefined berarti bahwa nilai variabel belum ditentukan; tidak diketahui berapa nilainya.
  • null berarti bahwa nilai variabel didefinisikan dan diatur ke nol (tidak memiliki nilai).

Marijn Haverbeke menyatakan, dalam bukunya yang gratis dan online, " Eloquent JavaScript " (penekanan saya):

Ada juga nilai yang sama, null, yang artinya 'nilai ini didefinisikan, tetapi tidak memiliki nilai'. Perbedaan makna antara undefined dan null sebagian besar bersifat akademis, dan biasanya tidak terlalu menarik. Dalam program-program praktis, seringkali perlu untuk memeriksa apakah sesuatu 'memiliki nilai'. Dalam kasus ini, ekspresi sesuatu == undefined dapat digunakan, karena, meskipun mereka tidak persis nilai yang sama, null == undefined akan menghasilkan true.

Jadi, saya kira cara terbaik untuk memeriksa apakah ada sesuatu yang tidak didefinisikan adalah:

if (something == undefined)

Semoga ini membantu!

Sunting: Menanggapi sunting Anda, properti objek harus bekerja dengan cara yang sama.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined
Pandincus
sumber
42
if (something == undefined) lebih baik ditulis seolah-olah (something === undefined)
Sebastian Rittau
59
Harus ditunjukkan bahwa ini tidak sepenuhnya aman. undefinedhanyalah sebuah variabel yang dapat ditugaskan kembali oleh pengguna: menulis undefined = 'a';akan menyebabkan kode Anda tidak lagi melakukan apa yang Anda pikirkan. Menggunakan typeoflebih baik dan juga berfungsi untuk variabel (bukan hanya properti) yang belum dideklarasikan.
Gabe Moothart
7
jika sesuatu adalah variabel global yang tidak terdefinisi, (sesuatu == tidak terdefinisi) memunculkan kesalahan javascript.
Morgan Cheng
8
Masalah dengan ini adalah bahwa jika var a = null maka a == undefined bernilai true, meskipun a paling pasti didefinisikan.
Andrew
6
Interpretasi dari komentar "Eloquent Javascript" ini terbelakang . Jika Anda benar-benar hanya ingin memeriksa undefined, kode yang disarankan tidak akan berfungsi (itu juga akan mendeteksi kondisi yang ditentukan tetapi belum ada nilai yang diasumsikan [ienull]). Nilai nol. Kode menyarankan "jika (sesuatu == terdefinisi) ..." cek untuk kedua terdefinisi dan nol (tidak ada nilai set), yaitu itu ditafsirkan sebagai "if ((sesuatu yang tidak terdefinisi) ATAU (sesuatu yang null)) ..." apa yang penulis katakan adalah bahwa sering apa yang Anda benar-benar inginkan adalah untuk memeriksa kedua terdefinisi dan null.
Chuck Kollars
125

Apa artinya ini: "properti objek tidak terdefinisi" ?

Sebenarnya itu bisa berarti dua hal yang sangat berbeda! Pertama, itu bisa berarti properti yang belum pernah didefinisikan dalam objek dan, kedua, itu bisa berarti properti yang memiliki nilai yang tidak ditentukan . Mari kita lihat kode ini:

var o = { a: undefined }

Apakah o.atidak terdefinisi? Iya! Nilainya tidak terdefinisi. Apakah o.btidak terdefinisi? Tentu! Tidak ada properti 'b' sama sekali! OK, lihat sekarang bagaimana berbagai pendekatan berbeda dalam kedua situasi:

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

Kita dapat dengan jelas melihat itu typeof obj.prop == 'undefined'dan obj.prop === undefinedsetara, dan mereka tidak membedakan situasi yang berbeda itu. Dan 'prop' in objdapat mendeteksi situasi ketika properti belum didefinisikan sama sekali dan tidak memperhatikan nilai properti yang mungkin tidak ditentukan.

Jadi apa yang harus dilakukan?

1) Anda ingin tahu apakah sebuah properti tidak terdefinisi dengan makna pertama atau kedua (situasi paling umum).

obj.prop === undefined // IMHO, see "final fight" below

2) Anda hanya ingin tahu apakah objek memiliki properti dan tidak peduli nilainya.

'prop' in obj

Catatan:

  • Anda tidak dapat memeriksa objek dan propertinya secara bersamaan. Misalnya, ini x.a === undefinedatau ini typeof x.a == 'undefined'muncul ReferenceError: x is not definedjika x tidak didefinisikan.
  • Variabel undefinedadalah variabel global (jadi sebenarnya ada window.undefineddi browser). Ini telah didukung sejak ECMAScript Edisi Pertama dan sejak ECMAScript 5 hanya dibaca . Jadi di browser modern, itu tidak dapat didefinisikan ulang menjadi benar karena banyak penulis suka menakuti kami, tetapi ini masih berlaku untuk browser yang lebih lama.

Pertarungan terakhir: obj.prop === undefinedvstypeof obj.prop == 'undefined'

Plus dari obj.prop === undefined:

  • Ini sedikit lebih pendek dan terlihat sedikit lebih cantik
  • Mesin JavaScript akan memberi Anda kesalahan jika Anda salah mengeja undefined

Kekurangan dari obj.prop === undefined:

  • undefined dapat diganti di browser lama

Plus dari typeof obj.prop == 'undefined':

  • Ini sangat universal! Ini berfungsi di browser baru dan lama.

Kekurangan dari typeof obj.prop == 'undefined':

  • 'undefned'( salah eja ) di sini hanyalah string konstan, jadi mesin JavaScript tidak dapat membantu Anda jika Anda salah mengeja seperti yang baru saja saya lakukan.

Pembaruan (untuk JavaScript sisi-server):

Node.js mendukung variabel global undefinedsebagai global.undefined(itu juga dapat digunakan tanpa awalan 'global'). Saya tidak tahu tentang implementasi lain dari JavaScript sisi server.

Konstantin Smolyanin
sumber
@Bergi terima kasih atas komentar Anda. Saya telah mengoreksi jawaban saya. Dalam pembelaan saya, saya dapat mengatakan bahwa saat ini (per v.0.10.18) dokumentasi Node.js resmi tidak mengatakan apa pun undefinedsebagai anggota global. Juga tidak console.log(global);juga for (var key in global) { ... }tidak menunjukkan tidak terdefinisi sebagai anggota global . Tapi tes suka 'undefined' in globalmenunjukkan yang sebaliknya.
Konstantin Smolyanin
4
Tidak memerlukan dokumentasi tambahan karena ini ada dalam spesifikasi EcmaScript , yang juga mengatakan itu [[Enumerable]]salah :-)
Bergi
5
Mengenai Minuses of typeof obj.prop == 'undefined', ini bisa dihindari dengan menulis sebagai typeof obj.prop == typeof undefined. Ini juga memberikan simetri yang sangat bagus.
hlovdal
3
@hlovdal: Itu benar-benar sia-sia vs obj.prop === undefined.
Ry-
1
Ketika kita benar pada tajuk utama pertanyaan " Mendeteksi properti yang tidak terdefinisi" , tidak berlaku untuk pertanyaan (berbeda dan jauh lebih mudah) dalam kalimat pertama ("periksa apakah tidak terdefinisi ..."), Anda menjawab if ('foo' in o) ... jawaban Anda benar-benar adalah jawaban benar pertama di sini. Cukup banyak orang lain hanya menjawab kalimat itu.
Frank Nocke
70

Masalahnya bermuara pada tiga kasus:

  1. Objek memiliki properti dan nilainya tidak undefined.
  2. Objek memiliki properti dan nilainya undefined.
  3. Objek tidak memiliki properti.

Ini memberitahu kita sesuatu yang saya anggap penting:

Ada perbedaan antara anggota yang tidak ditentukan dan anggota yang ditentukan dengan nilai yang tidak ditentukan.

Namun sayangnya typeof obj.footidak memberi tahu kami mana dari tiga kasus yang kami miliki. Namun kita dapat menggabungkan ini dengan "foo" in objuntuk membedakan kasus.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

Perlu dicatat bahwa tes ini juga sama untuk nullentri

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

Saya berpendapat bahwa dalam beberapa kasus lebih masuk akal (dan lebih jelas) untuk memeriksa apakah properti itu ada, daripada memeriksa apakah itu tidak terdefinisi, dan satu-satunya kasus di mana cek ini akan berbeda adalah kasus 2, kasus langka dari entri aktual dalam objek dengan nilai yang tidak ditentukan.

Sebagai contoh: Saya baru saja refactoring sekelompok kode yang memiliki banyak pemeriksaan apakah suatu objek memiliki properti yang diberikan.

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

Yang lebih jelas ketika ditulis tanpa tanda centang untuk yang tidak ditentukan.

if( "x" in blob ) { fn(blob.x); }

Tetapi seperti yang telah disebutkan ini tidak persis sama (tetapi lebih dari cukup baik untuk kebutuhan saya).

Michael Anderson
sumber
10
Hai Michael. Saran yang bagus, dan saya pikir itu membuat semuanya lebih bersih. Satu gotcha yang saya temukan, bagaimanapun, adalah ketika menggunakan! operator dengan "dalam". Anda harus mengatakan if (!("x" in blob)) {}dengan tanda kurung di dalam, karena! Operator lebih diutamakan daripada 'dalam'. Semoga itu bisa membantu seseorang.
Simon East
Maaf Michael, tapi ini tidak benar, atau setidaknya menyesatkan, mengingat pertanyaan aslinya. 'in' bukan cara yang cukup untuk menguji apakah properti objek memiliki tipe yang tidak terdefinisi. Sebagai buktinya, silakan lihat biola ini: jsfiddle.net/CsLKJ/4
tex
2
Kedua bagian kode itu melakukan hal yang berbeda! Pertimbangkan dan objek yang diberikan oleh a = {b: undefined}; typeof a.b === typeof a.c === 'undefined'tapi kemudian 'b' in adan !('c' in a).
mgol
3
+1. OP tidak memperjelas apakah properti itu ada dan nilainya tidak terdefinisi , atau apakah properti itu sendiri tidak terdefinisi (yaitu tidak ada).
RobG
Saya akan menyarankan perubahan titik (2.) di tabel pertama Anda { x : undefined }atau setidaknya menambahkannya sebagai alternatif lain (2.) di tabel - saya harus berpikir sejenak untuk menyadari titik itu (2.) mengevaluasi ke undefined(meskipun Anda menyebutkannya nanti).
mucaho
46
if ( typeof( something ) == "undefined") 

Ini bekerja untuk saya sedangkan yang lain tidak.

Kevin
sumber
47
parens tidak diperlukan karena typeof adalah operator
aehlke
12
Tetapi mereka memperjelas apa yang sedang diperiksa. Kalau tidak, itu mungkin dibaca sebagai typeof (something == "undefined").
Abhi Beckert
Jika Anda membutuhkan tanda kurung, maka Anda harus mempelajari prioritas operator di JS: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ian
11
Parenthesis berguna justru karena Anda TIDAK perlu mempelajari prioritas operator di JS, Anda juga tidak perlu berspekulasi apakah pemrogram pemeliharaan di masa depan perlu mempelajari prioritas operator di JS.
DaveWalley
27
Parenthesis berguna untuk mengklarifikasi hal-hal. Tetapi dalam kasus ini mereka hanya membuat operator terlihat seperti fungsi. Tidak diragukan lagi ini menjelaskan maksud programmer. Tetapi jika Anda tidak yakin tentang prioritas operator, Anda sebaiknya menuliskannya (typeof something) === "undefined".
Robert
42

Saya tidak yakin dari mana asal menggunakan ===dengan typeof, dan sebagai konvensi saya melihatnya digunakan di banyak perpustakaan, tetapi typeof operator mengembalikan string literal, dan kami tahu itu di muka, jadi mengapa Anda juga ingin mengetik periksa juga?

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient
Eric
sumber
Poin bagus Eric. Apakah ada hit kinerja dari memeriksa jenis juga?
Simon East
5
@Simon: cukup sebaliknya - orang bisa mengharapkan sedikit kinerja dari menghindari paksaan dalam kasus '==='. Tes cepat dan kotor menunjukkan '===' 5% lebih cepat daripada '==' di bawah FF5.0.1
Antony Hatchkins
5
Tes yang lebih menyeluruh menunjukkan bahwa di bawah FF, IE dan Chrome '==' lebih atau kurang lebih cepat daripada '===' (5-10%) dan Opera tidak membuat perbedaan sama sekali: jsperf.com/triple- equals-vs-twice-equals / 6
Antony Hatchkins
3
Menggunakan ==masih membutuhkan setidaknya pemeriksaan tipe - penerjemah tidak dapat membandingkan kedua operan tanpa mengetahui jenis operannya terlebih dahulu.
Alnitak
7
==adalah satu karakter kurang dari ===:)
svidgen
25

Crossposting jawaban saya dari pertanyaan terkait Bagaimana cara memeriksa "tidak terdefinisi" dalam JavaScript?

Khusus untuk pertanyaan ini, lihat uji kasus dengan someObject.<whatever>.


Beberapa skenario yang menggambarkan hasil dari berbagai jawaban: http://jsfiddle.net/drzaus/UVjM4/

(Perhatikan bahwa penggunaan tes varuntuk inmembuat perbedaan ketika di bungkus scoped)

Kode untuk referensi:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.log(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

Dan hasil:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined
drzaus
sumber
21

Jika kamu melakukan

if (myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

itu akan gagal ketika variabel myvartidak ada, karena myvar tidak didefinisikan, sehingga skrip rusak dan tes tidak berpengaruh.

Karena objek jendela memiliki cakupan global (objek default) di luar fungsi, deklarasi akan 'dilampirkan' ke objek jendela.

Sebagai contoh:

var myvar = 'test';

Variabel global myvar sama dengan window.myvar atau window ['myvar']

Untuk menghindari kesalahan saat menguji ketika variabel global ada, Anda lebih baik menggunakan:

if(window.myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

Pertanyaan jika suatu variabel benar-benar ada tidak masalah, nilainya tidak benar. Kalau tidak, konyol untuk menginisialisasi variabel dengan tidak terdefinisi, dan lebih baik menggunakan nilai false untuk menginisialisasi. Ketika Anda tahu bahwa semua variabel yang Anda nyatakan diinisialisasi dengan false, Anda bisa langsung memeriksa tipenya atau mengandalkan !window.myvaruntuk memeriksa apakah itu memiliki nilai yang tepat / valid. Jadi bahkan ketika variabel tidak didefinisikan maka !window.myvaradalah sama untuk myvar = undefinedatau myvar = falseatau myvar = 0.

Saat Anda mengharapkan jenis tertentu, uji jenis variabel. Untuk mempercepat pengujian suatu kondisi sebaiknya Anda lakukan:

if( !window.myvar || typeof window.myvar != 'string' )
{
    alert('var does not exists or is not type of string');
}

Ketika kondisi pertama dan sederhana benar, penerjemah melewatkan tes berikutnya.

Itu selalu lebih baik untuk menggunakan instance / objek variabel untuk memeriksa apakah itu mendapat nilai yang valid. Ini lebih stabil dan merupakan cara pemrograman yang lebih baik.

(y)

Codebeat
sumber
19

Saya tidak melihat (harap saya tidak ketinggalan) ada orang yang memeriksa objek sebelum properti. Jadi, ini adalah yang terpendek dan paling efektif (walaupun tidak harus yang paling jelas):

if (obj && obj.prop) {
  // Do something;
}

Jika obj atau obj.prop tidak terdefinisi, null, atau "falsy", pernyataan if tidak akan menjalankan blok kode. Ini biasanya perilaku yang diinginkan di sebagian besar pernyataan blok kode (dalam JavaScript).

Joe Johnson
sumber
2
Jika Anda ingin tahu mengapa ini bekerja: Javascript: Logical Operator dan truthy /
falsy
jika Anda ingin menetapkan properti ke variabel jika itu didefinisikan, bukan null dan bukan falsey, kalau tidak gunakan beberapa nilai default, Anda dapat menggunakan: var x = obj && obj.prop || 'default';
Stijn de Witt
Saya percaya pertanyaannya adalah untuk memeriksa terhadap yang tidak ditentukan secara eksplisit. Kondisi Anda memeriksa semua nilai JS yang salah.
NikoKyriakid
15

Dalam artikel Menjelajahi Jurang Null dan Undefined dalam JavaScript saya membaca bahwa kerangka kerja seperti Underscore.js menggunakan fungsi ini:

function isUndefined(obj){
    return obj === void 0;
}
Marthijn
sumber
3
void 0hanyalah cara singkat untuk menulis undefined(karena itu adalah kekosongan yang diikuti oleh setiap ekspresi yang dikembalikan), ini menghemat 3 karakter. Bisa juga var a; return obj === a;, tapi itu satu karakter lagi. :-)
RobG
2
voidadalah kata yang dilindungi undang-undang, padahal undefinedtidak berarti sementara undefinedsama dengan void 0secara default, Anda dapat menetapkan nilai ke undefinedmisalnya undefined = 1234.
Brian M. Hunt
isUndefined(obj): 16 karakter. obj === void 0: 14 karakter. 'cukup kata.
Stijn de Witt
14

Sederhananya apa pun yang tidak didefinisikan dalam JavaScript, tidak terdefinisi , tidak masalah apakah itu properti di dalam Obyek / Array atau hanya sebagai variabel sederhana ...

JavaScript memiliki typeofyang membuatnya sangat mudah untuk mendeteksi variabel yang tidak terdefinisi.

Cukup periksa apakah typeof whatever === 'undefined'dan itu akan mengembalikan boolean.

Begitulah cara fungsi terkenal isUndefined()di AngularJs v.1x ditulis:

function isUndefined(value) {return typeof value === 'undefined';} 

Jadi, ketika Anda melihat fungsi menerima nilai, jika nilai itu didefinisikan, itu akan kembali false, jika tidak, untuk nilai yang tidak ditentukan, kembali true.

Jadi mari kita lihat apa yang akan menjadi hasil ketika kita melewati nilai, termasuk properti objek seperti di bawah ini, ini adalah daftar variabel yang kita miliki:

var stackoverflow = {};
stackoverflow.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;

dan kami memeriksanya seperti di bawah ini, Anda dapat melihat hasilnya di depan mereka sebagai komentar:

isUndefined(stackoverflow); //false
isUndefined(stackoverflow.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(stackoverflow.java); //true
isUndefined(stackoverflow.php); //true
isUndefined(stackoverflow && stackoverflow.css); //true

Seperti yang Anda lihat, kami dapat memeriksa apa pun dengan menggunakan sesuatu seperti ini dalam kode kami, seperti yang disebutkan, Anda hanya dapat menggunakan typeofdalam kode Anda, tetapi jika Anda menggunakannya berulang-ulang, buat fungsi seperti sampel sudut yang saya bagikan dan tetap gunakan kembali sebagai mengikuti pola kode KERING.

Juga satu hal lagi, untuk memeriksa properti pada objek dalam aplikasi nyata yang Anda tidak yakin bahkan objek tersebut ada atau tidak, periksa apakah objek tersebut ada terlebih dahulu.

Jika Anda memeriksa properti pada objek dan objek tidak ada, akan menimbulkan kesalahan dan menghentikan seluruh aplikasi yang berjalan.

isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)

Sangat sederhana, Anda dapat membungkus di dalam pernyataan if seperti di bawah ini:

if(typeof x !== 'undefined') {
  //do something
}

Yang juga sama dengan yang didefinisikan dalam Angular 1.x ...

function isDefined(value) {return typeof value !== 'undefined';}

Juga kerangka kerja javascript lain seperti underscore memiliki pemeriksaan definisi yang serupa, tetapi saya sarankan Anda menggunakan typeofjika Anda sudah tidak menggunakan kerangka kerja apa pun.

Saya juga menambahkan bagian ini dari MDN yang telah mendapat informasi berguna tentang typeof, undefined dan void (0).

Kesetaraan yang ketat dan tidak terdefinisi
Anda dapat menggunakan operator kesetaraan dan ketidaksetaraan yang ketat dan tidak ditentukan untuk menentukan apakah suatu variabel memiliki nilai. Dalam kode berikut, variabel x tidak didefinisikan, dan pernyataan if mengevaluasi ke true.

var x;
if (x === undefined) {
   // these statements execute
}
else {
   // these statements do not execute
}

Catatan: Operator kesetaraan yang ketat dan bukan operator kesetaraan standar harus digunakan di sini, karena x == undefined juga memeriksa apakah x adalah nol, sedangkan kesetaraan yang ketat tidak. null tidak sama dengan undefined. Lihat operator perbandingan untuk detailnya.


Typeof operator dan undefined
Atau, typeof dapat digunakan:

var x;
if (typeof x === 'undefined') {
   // these statements execute
}

Salah satu alasan untuk menggunakan typeof adalah bahwa itu tidak menimbulkan kesalahan jika variabel belum dideklarasikan.

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
   // these statements execute
}

if (x === undefined) { // throws a ReferenceError

}

Namun, teknik semacam ini harus dihindari. JavaScript adalah bahasa yang dibatasi secara statis, jadi mengetahui jika suatu variabel dideklarasikan dapat dibaca dengan melihat apakah itu dinyatakan dalam konteks terlampir. Satu-satunya pengecualian adalah ruang lingkup global, tetapi ruang lingkup global terikat pada objek global, sehingga memeriksa keberadaan variabel dalam konteks global dapat dilakukan dengan memeriksa keberadaan properti pada objek global (menggunakan operator dalam, contohnya).


Operator batal dan tidak terdefinisi

Operator batal adalah alternatif ketiga.

var x;
if (x === void 0) {
   // these statements execute
}

// y has not been declared before
if (y === void 0) {
   // throws a ReferenceError (in contrast to `typeof`)
}

lebih banyak> di sini

Alireza
sumber
13

' jika (window.x) {} ' aman dari kesalahan

Kemungkinan besar Anda inginkan if (window.x). Pemeriksaan ini aman walaupun x belum dideklarasikan ( var x;) - browser tidak menampilkan kesalahan.

Contoh: Saya ingin tahu apakah browser saya mendukung History API

if (window.history) {
    history.call_some_function();
}

Bagaimana ini bekerja:

window adalah objek yang menampung semua variabel global sebagai anggotanya, dan adalah sah untuk mencoba mengakses anggota yang tidak ada. Jika x belum dinyatakan atau belum disetel maka window.xpengembalian tidak terdefinisi . lead yang tidak terdefinisi ke false ketika if () mengevaluasinya.

DenisS
sumber
Tetapi bagaimana jika Anda menjalankan di Node? typeof history != 'undefined'sebenarnya bekerja di kedua sistem.
Stijn de Witt
13

Membaca ini, saya kagum saya tidak melihat ini. Saya telah menemukan banyak algoritma yang akan bekerja untuk ini.

Tidak Didefinisikan

Jika nilai suatu objek tidak pernah didefinisikan, ini akan mencegah dari kembali truejika itu didefinisikan sebagai nullatau undefined. Ini berguna jika Anda ingin benar dikembalikan untuk nilai yang ditetapkan sebagaiundefined

if(obj.prop === void 0) console.log("The value has never been defined");

Didefinisikan sebagai tidak terdefinisi atau Tidak pernah Didefinisikan

Jika Anda ingin hasilnya trueuntuk nilai-nilai yang didefinisikan dengan nilai undefined, atau tidak pernah didefinisikan, Anda dapat menggunakannya=== undefined

if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");

Didefinisikan sebagai nilai falsy, undefined, null, atau tidak pernah didefinisikan.

Secara umum, orang-orang telah meminta saya untuk algoritma untuk mencari tahu apakah suatu nilai salah undefined,, atau null. Pekerjaan berikut.

if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
    console.log("The value is falsy, null, or undefined");
}
Travis
sumber
4
Saya pikir Anda dapat mengganti contoh terakhir denganif (!obj.prop)
Stijn de Witt
@StijndeWitt, Anda bisa, saya cukup tidak berpengalaman ketika saya menulis ini, dan bahasa Inggris saya tampaknya sama buruknya, namun, tidak ada yang salah dalam jawabannya
Travis
3
var obj = {foo: undefined}; obj.foo === void 0-> true. Bagaimana itu "tidak pernah didefinisikan sebagai undefined"? Ini salah.
Patrick Roberts
@ PatrickRoberts Anda benar. Ketika saya menulis jawaban ini pada Februari 2015 (sebelum ES6) opsi pertama yang saya uraikan memang berhasil, tetapi sekarang sudah usang.
Travis
12
"propertyName" in obj //-> true | false
sam
sumber
10

Dibandingkan dengan void 0 , untuk kesederhanaan.

if (foo !== void 0)

Ini tidak selektif if (typeof foo !== 'undefined')

bevacqua
sumber
3
Tapi itu akan melempar ReferenceError jika footidak dideklarasikan.
daniel1426
1
@ daniel1426: Jadi, jika ada kesalahan dalam kode Anda, Anda ingin menyembunyikannya daripada memperbaikinya? Bukan pendekatan yang bagus, IMO.
Ini tidak digunakan untuk menyembunyikan kesalahan. Ini adalah cara umum untuk mendeteksi sifat-sifat lingkungan untuk mendefinisikan polyfill. Sebagai contoh: if (typeof Promise === 'undefined') {/ * define Promise * /}
gaperton
10

Solusinya salah. Dalam JavaScript,

null == undefined

akan kembali benar, karena mereka berdua "dicor" ke boolean dan salah. Cara yang benar adalah dengan memeriksa

if (something === undefined)

yang merupakan operator identitas ...

Ricky
sumber
3
Untuk menjadi jelas, ===adalah ketik kesetaraan + (persamaan primitif | identitas objek), di mana primitif mencakup string. Saya pikir kebanyakan orang menganggap tidak 'abab'.slice(0,2) === 'abab'.slice(2)intuitif jika seseorang menganggap ===sebagai operator identitas.
clacke
1
Salah. Ini melempar kesalahan jika variabel belum dibuat. Tidak boleh dipilih. Gunakan typeof sebagai gantinya.
Simon East
10

Anda bisa mendapatkan array yang tidak terdefinisi dengan path menggunakan kode berikut.

 function getAllUndefined(object) {

        function convertPath(arr, key) {
            var path = "";
            for (var i = 1; i < arr.length; i++) {

                path += arr[i] + "->";
            }
            path += key;
            return path;
        }


        var stack = [];
        var saveUndefined= [];
        function getUndefiend(obj, key) {

            var t = typeof obj;
            switch (t) {
                case "object":
                    if (t === null) {
                        return false;
                    }
                    break;
                case "string":
                case "number":
                case "boolean":
                case "null":
                    return false;
                default:
                    return true;
            }
            stack.push(key);
            for (k in obj) {
                if (obj.hasOwnProperty(k)) {
                    v = getUndefiend(obj[k], k);
                    if (v) {
                        saveUndefined.push(convertPath(stack, k));
                    }
                }
            }
            stack.pop();

        }

        getUndefiend({
            "": object
        }, "");
        return saveUndefined;
    }

tautan jsFiddle

Anoop
sumber
Meskipun tidak akan memengaruhi validitas kode Anda, Anda salah ketik: getUndefiendseharusnya getUndefined.
icktoofay
8

Inilah situasi saya:

Saya menggunakan hasil panggilan REST. Hasilnya harus diuraikan dari JSON ke objek JavaScript.

Ada satu kesalahan yang harus saya pertahankan. Jika args ke panggilan sisanya salah sejauh pengguna menentukan args salah, panggilan sisanya kembali pada dasarnya kosong.

Saat menggunakan pos ini untuk membantu saya bertahan melawan ini, saya mencoba ini.

if( typeof restResult.data[0] === "undefined" ) { throw  "Some error"; }

Untuk situasi saya, jika restResult.data [0] === "objek", maka saya dapat dengan aman mulai memeriksa anggota lainnya. Jika tidak terdefinisi maka lemparkan kesalahan seperti di atas.

Apa yang saya katakan adalah bahwa untuk situasi saya, semua saran di atas dalam posting ini tidak berfungsi. Saya tidak mengatakan saya benar dan semua orang salah. Saya bukan master JavaScript sama sekali, tetapi mudah-mudahan ini akan membantu seseorang.

wayneseymour
sumber
typeofPenjaga Anda sebenarnya tidak berjaga-jaga terhadap apa pun yang tidak bisa dilakukan perbandingan langsung. Jika restResulttidak terdefinisi atau tidak dideklarasikan, ia masih akan membuang.
Dalam kasus Anda, Anda bisa lebih mudah memeriksa apakah array kosong:if(!restResult.data.length) { throw "Some error"; }
Headbank
8

Ada cara yang bagus & elegan untuk menetapkan properti yang ditentukan ke variabel baru jika itu didefinisikan atau menetapkan nilai default untuk itu sebagai fallback jika itu tidak ditentukan.

var a = obj.prop || defaultValue;

Ini cocok jika Anda memiliki fungsi, yang menerima properti konfigurasi tambahan:

var yourFunction = function(config){

   this.config = config || {};
   this.yourConfigValue = config.yourConfigValue || 1;
   console.log(this.yourConfigValue);

}

Sekarang sedang mengeksekusi

yourFunction({yourConfigValue:2});
//=> 2

yourFunction();
//=> 1

yourFunction({otherProperty:5});
//=> 1
Marian Klühspies
sumber
7

Semua jawaban tidak lengkap. Ini adalah cara yang tepat untuk mengetahui bahwa ada properti 'didefinisikan sebagai tidak terdefinisi':

var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
  return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
} ;

Contoh:

var a = { b : 1, e : null } ;
a.c = a.d ;

hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
hasUndefinedProperty(a, 'd') ; // false : d is undefined
hasUndefinedProperty(a, 'e') ; // false : e is defined as null

// And now...
delete a.c ;
hasUndefinedProperty(a, 'c') ; // false : c is undefined

Sayang sekali ini jawaban yang benar dikubur dalam jawaban yang salah> _ <

Jadi, bagi siapa saja yang lewat, aku akan memberimu undefined gratis !!

var undefined ; undefined ; // undefined
({}).a ;                    // undefined
[].a ;                      // undefined
''.a ;                      // undefined
(function(){}()) ;          // undefined
void(0) ;                   // undefined
eval() ;                    // undefined
1..a ;                      // undefined
/a/.a ;                     // undefined
(true).a ;                  // undefined
Juan Garcia
sumber
7

Melewati komentar, bagi mereka yang ingin memeriksa keduanya apakah tidak terdefinisi atau nilainya nol:

//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
    alert('either it is undefined or value is null')
}

Jika Anda menggunakan jQuery Library maka jQuery.isEmptyObject()cukup untuk kedua kasus,

var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;

s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;

//Usage
if (jQuery.isEmptyObject(s)) {
    alert('Either variable:s is undefined or its value is null');
} else {
     alert('variable:s has value ' + s);
}

s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;
Angelin Nadar
sumber
jQuery juga akan menangani masalah kompatibilitas lintas browser dengan JavaScript API yang berbeda.
Henry Heleine
7

Jika Anda menggunakan Angular:

angular.isUndefined(obj)
angular.isUndefined(obj.prop)

Underscore.js:

_.isUndefined(obj) 
_.isUndefined(obj.prop) 
Vitalii Fedorenko
sumber
2
Bagaimana saya menambah 1variabel x? Apakah saya perlu Garis Bawah atau jQuery? (Sungguh menakjubkan bahwa orang akan menggunakan perpustakaan bahkan untuk operasi paling dasar seperti typeofcek)
Stijn de Witt
6

Saya gunakan if (this.variable)untuk menguji apakah itu didefinisikan. Sederhana if (variable), disarankan di atas , gagal untuk saya. Ternyata itu hanya berfungsi ketika variabel adalah bidang dari beberapa objek, obj.someFielduntuk memeriksa apakah itu didefinisikan dalam kamus. Tapi kita bisa menggunakan thisatau windowsebagai objek kamus karena variabel apa pun adalah bidang di jendela saat ini, seperti yang saya mengerti. Karena itu inilah ujiannya

if (this.abc) alert("defined"); else alert("undefined");

abc = "abc";
if (this.abc) alert("defined"); else alert("undefined");

Pertama mendeteksi bahwa variabel abctidak terdefinisi dan didefinisikan setelah inisialisasi.

Val
sumber
5

Saya memberikan tiga cara di sini bagi mereka yang mengharapkan jawaban aneh:

function isUndefined1(val) {
    try {
        val.a;
    } catch (e) {
        return /undefined/.test(e.message);
    }
    return false;
}
function isUndefined2(val) {
    return !val && val+'' === 'undefined';
}
function isUndefined3(val) {
    const defaultVal={};
    return ((input=defaultVal)=>input===defaultVal)(val);
}
function test(func){
    console.group(`test start :`+func.name);
    console.log(func(undefined));
    console.log(func(null));
    console.log(func(1));
    console.log(func("1"));
    console.log(func(0));
    console.log(func({}));
    console.log(func(function () { }));
    console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);

isUndefined1:

Cobalah untuk mendapatkan properti dari nilai input, periksa pesan kesalahan jika ada. Jika nilai input tidak terdefinisi, pesan kesalahan adalah Uncaught TypeError: Tidak dapat membaca properti 'b' dari undefined

isUndefined2:

Konversi nilai input ke string untuk dibandingkan dengan "undefined"dan pastikan itu nilai negatif.

isUndefined3:

Dalam js, parameter opsional berfungsi saat nilai input tepat undefined.

blackmiaool
sumber
5

ES2019 memperkenalkan fitur baru - perangkaian opsional yang dapat Anda gunakan untuk menggunakan properti objek hanya ketika objek didefinisikan seperti ini:

const userPhone = user?.contactDetails?.phone;

Ini akan merujuk ke properti ponsel hanya ketika pengguna dan data kontak didefinisikan.

Ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

Przemek Struciński
sumber
Saya biasa menggunakan banyak fungsi yang didapat dari lodash, sangat nyaman untuk mengakses objek semacam ini, tetapi perangkaian opsional baru menutupi sebagian besar penggunaan _.get
Al Hill
4
function isUnset(inp) {
  return (typeof inp === 'undefined')
}

Mengembalikan nilai false jika variabel disetel, dan true jika tidak terdefinisi.

Kemudian gunakan:

if (isUnset(var)) {
  // initialize variable here
}
Rixius
sumber
5
Tidak. Jangan lakukan ini. Hanya dibutuhkan tes yang sangat sederhana untuk membuktikan bahwa Anda tidak dapat menyelesaikan typeoftes dalam suatu fungsi. Luar biasa bahwa 4 orang menaikkan peringkat ini. -1.
Stijn de Witt
4

Saya ingin menunjukkan kepada Anda sesuatu yang saya gunakan untuk melindungi undefinedvariabel:

Object.defineProperty(window, 'undefined', {});

Ini melarang siapa pun untuk mengubah window.undefinednilai karena itu menghancurkan kode berdasarkan variabel itu. Jika menggunakan "use strict", apa pun yang mencoba mengubah nilainya akan berakhir dengan kesalahan, jika tidak maka akan diabaikan secara diam-diam.

Seti
sumber
4

Anda juga dapat menggunakan Proksi, ini akan berfungsi dengan panggilan bersarang, tetapi akan memerlukan satu pemeriksaan tambahan:

function resolveUnknownProps(obj, resolveKey) {
  const handler = {
    get(target, key) {
      if (
        target[key] !== null &&
        typeof target[key] === 'object'
      ) {
        return resolveUnknownProps(target[key], resolveKey);
      } else if (!target[key]) {
        return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
      }

      return target[key];
    },
  };

  return new Proxy(obj, handler);
}

const user = {}

console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }

jadi kamu akan menggunakannya seperti:

const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
  // do someting
}
Sarkis Arutiunian
sumber