Bisakah saya menetapkan variabel ke undefined atau meneruskan undefined sebagai argumen?

304

Saya agak bingung tentang JavaScript undefineddan nullnilai - nilai.

Apa yang if (!testvar)sebenarnya dilakukan? Apakah tes untuk undefineddan nullatau hanya undefined?

Setelah variabel didefinisikan, bisakah saya menghapusnya kembali undefined(karena itu menghapus variabel)?

Bisakah saya lulus undefinedsebagai parameter? Misalnya:

function test(var1, var2, var3) {

}

test("value1", undefined, "value2");
AJ.
sumber

Jawaban:

514

Saya agak bingung tentang Javascript tidak terdefinisi & nol.

Jangan bingung null. Biasanya masuk akal dan berperilaku mirip dengan konsep bahasa scripting lain 'out-of-band' null ',' nil 'atau' None '.

undefined, di sisi lain, adalah kekhasan JavaScript yang aneh. Ini adalah objek tunggal yang mewakili nilai out-of-band, pada dasarnya kedua serupa-tetapi-berbeda null. Itu muncul:

  1. Saat Anda memanggil fungsi dengan argumen lebih sedikit dari daftar argumen di daftar functionpernyataan, argumen yang tidak dilimpahkan diatur ke undefined. Anda dapat menguji untuk itu dengan misalnya .:

    function dosomething(arg1, arg2) {
        if (arg2===undefined)
        arg2= DEFAULT_VALUE_FOR_ARG2;
        ...
    }

    Dengan metode ini Anda tidak dapat membedakan antara dosomething(1)dan dosomething(1, undefined); arg2akan bernilai sama di keduanya. Jika Anda perlu memberi tahu perbedaannya, Anda dapat melihatnya arguments.length, tetapi melakukan argumen opsional seperti itu umumnya tidak terlalu mudah dibaca.

  2. Ketika suatu fungsi tidak return value;, itu kembali undefined. Biasanya tidak perlu menggunakan hasil pengembalian seperti itu.

  3. Saat Anda mendeklarasikan variabel dengan memiliki var apernyataan di blok, tetapi belum menetapkan nilainya, itu adalah undefined. Sekali lagi, Anda seharusnya tidak perlu bergantung pada itu.

  4. typeofOperator seram kembali 'undefined'ketika operan adalah variabel sederhana yang tidak ada, alih-alih melempar kesalahan seperti biasa terjadi jika Anda mencoba merujuknya. (Anda juga bisa memberikan variabel sederhana yang dibungkus dengan tanda kurung, tetapi bukan ekspresi penuh yang melibatkan variabel yang tidak ada.) Tidak banyak gunanya juga.

  5. Ini yang kontroversial. Ketika Anda mengakses properti dari objek yang tidak ada, Anda tidak langsung mendapatkan kesalahan seperti dalam setiap bahasa lainnya. Sebaliknya Anda mendapatkan undefinedobjek. (Dan kemudian ketika Anda mencoba untuk menggunakan undefinedobjek itu nanti dalam skrip itu akan salah dengan cara yang aneh yang jauh lebih sulit untuk dilacak daripada jika JavaScript baru saja melemparkan kesalahan langsung.)

    Ini sering digunakan untuk memeriksa keberadaan properti:

    if (o.prop!==undefined) // or often as truthiness test, if (o.prop)
       ...do something...

    Namun, karena Anda dapat menetapkan undefinedseperti nilai lainnya:

    o.prop= undefined;

    itu tidak benar-benar mendeteksi apakah properti itu ada di sana dengan andal. Lebih baik menggunakan inoperator, yang bukan dalam versi Netscape asli JavaScript, tetapi tersedia di mana-mana sekarang:

    if ('prop' in o)
        ...

Singkatnya, undefinedadalah kekacauan khusus JavaScript, yang membingungkan semua orang. Terlepas dari argumen fungsi opsional, di mana JS tidak memiliki mekanisme lain yang lebih elegan, undefinedharus dihindari. Seharusnya tidak pernah menjadi bagian dari bahasa; nullakan bekerja dengan baik untuk (2) dan (3), dan (4) adalah kesalahan yang hanya ada karena pada awalnya JavaScript tidak memiliki pengecualian.

apa yang if (!testvar)sebenarnya dilakukan Apakah tes untuk undefined dan null atau hanya undefined?

Seperti pemeriksaan tes 'truthiness' melawan false, undefined,null , 0, NaNdan string kosong. Tapi dalam kasus ini, ya, itu benar undefined- benar diperhatikan. IMO, itu harus lebih eksplisit tentang itu dan katakan if (testvar!==undefined).

setelah suatu variabel didefinisikan dapatkah saya menghapusnya kembali ke tidak terdefinisi (karena itu menghapus variabel).

Anda tentu dapat menetapkannya undefined, tetapi itu tidak akan menghapus variabel. Hanya delete object.propertyoperator yang benar-benar menghapus barang.

deletebenar-benar dimaksudkan untuk properti daripada variabel seperti itu. Peramban akan membiarkan Anda lolos dengan lurus delete variable, tetapi itu bukan ide yang baik dan tidak akan berfungsi dalam mode ketat ECMAScript Fifth Edition. Jika Anda ingin membebaskan referensi ke sesuatu sehingga dapat dikumpulkan dengan sampah, itu akan lebih biasa dikatakan variable= null.

dapatkah saya melewatkan parameter yang tidak ditentukan?

Iya.

bobince
sumber
10
Sungguh jawaban yang fantastis. Saya baru saja gagal dalam tes JavaScript: perfectionkills.com/javascript-quiz Nanti saya akan membaca kembali jawaban Anda dan mencoba tes lagi!
Skilldrick
1
diperbaiki, ta. (Saya cenderung tidak terlalu khawatir tentang penugasan kembali, karena ada begitu banyak hal yang dapat didefinisikan ulang oleh sebuah naskah untuk mengacaukan semuanya sehingga kasus umum tidak mungkin diselesaikan.)
bobince
2
@obobince undefinedadalah objek tunggal? Maksud kamu apa? Ini nilai primitif, dan bukan objek.
Šime Vidas
2
@ Hortensi: Itulah poinnya (4). Saya biasanya tidak mau typeof foo=='undefined'; ini cenderung digunakan untuk (4a) mengendus global, dalam hal ini saya lebih suka untuk secara eksplisit dan mengatakan 'foo' in window, atau (4b) menguji terhadap undefined-nilai itu sendiri, dalam hal ini saya lebih suka dibaca dan berkata foo===undefined. Secara teori pengujian typeofterhadap 'undefined'bisa menggunakan use case yang tidak bisa diberikan oleh konstruk lain: mengendus keberadaan variabel lokal. Namun pada kenyataannya Anda hampir selalu tahu variabel apa yang dinyatakan lokal.
bobince
4
Satu peringatan dengan # 2, biasanya fungsi tanpa returnpernyataan kembali undefined, tetapi jika fungsinya adalah konstruktor (dipanggil dengan newoperator) itu akan mengembalikan objek baru (nilai thisdi dalam konstruktor) meskipun tidak memiliki returnpernyataan. console.log((function (){}()));kembali undefined. console.log((new function (){}()));mengembalikan objek.
Kode Tidak Berguna
18

Anda tidak dapat (tidak?) Mendefinisikan sesuatu sebagai tidak terdefinisi, karena variabel tidak lagi ditentukan - Anda baru saja mendefinisikan menjadi sesuatu.

Anda tidak dapat (tidak boleh?) Beralih undefinedke suatu fungsi. Jika Anda ingin memberikan nilai kosong, gunakannull saja.

Pernyataan itu if(!testvar)memeriksa nilai benar / salah boolean, yang satu ini menguji apakah testvardievaluasi atau tidak false. Menurut definisi, nulldan undefinedtidak boleh dievaluasi bukan sebagai trueatau false, tetapi JavaScript mengevaluasi nullsebagaifalse , dan memberikan kesalahan jika Anda mencoba untuk mengevaluasi variabel yang tidak terdefinisi.

Untuk benar menguji undefinedatau null, gunakan ini:

if(typeof(testvar) === "undefined") { ... }

if(testvar === null) { ... }
Tatu Ulmanen
sumber
1
Triple-equals memeriksa tipe juga, jadi tidak ada tipe paksaan yang dilakukan. Douglas Crockford menyarankan agar tidak menggunakan operator tipe-paksaan ( ==dan !=).
Skilldrick
3
Anda dapat mendefinisikan sesuatu sebagai tidak terdefinisi. var a= undefined. Anda bisa lulus fn(undefined). Jika Anda ingin menemukan perbedaan antara properti yang tidak terdefinisi pdari objek o, dan properti pyang telah ditentukan dan ditetapkan undefined, Anda harus menggunakan 'p' in ooperator.
bobince
1
Apakah ada alasan mengapa seseorang tidak boleh menguji testvar === undefineddaripada yang lebih rumit typeof(testvar) === "undefined"?
ddaa
4
Ada alasan lain yang baik untuk menggunakan typeoftes untuk variabel yang tidak terdefinisi: tidak seperti null, undefinedhanyalah properti dari objek global dan dapat dengan sendirinya didefinisikan ulang. Hanya membutuhkan gaya pengkodean tertentu dan tanda sama dengan yang hilang dan undefineddiam-diam diubah:if (undefined = someVar) {...}
Tim Down
1
@IanGrainger: ECMAScript 5 (diimplementasikan dalam versi semua browser saat ini) sebagian besar memperbaikinya dengan membuat undefinedproperti yang tidak berubah dari objek global, jadi lebih aman daripada sebelumnya. Namun, masih mungkin untuk mendefinisikan variabel yang dapat diubah yang disebut undefineddalam suatu fungsi, sehingga masalahnya belum sepenuhnya hilang.
Tim Down
13

Perbedaan dasarnya adalah itu undefineddan nullmewakili konsep yang berbeda.

Jika hanya nulltersedia, Anda tidak akan dapat menentukan apakah nullditetapkan secara sengaja sebagai nilai atau apakah nilai belum ditetapkan, kecuali jika Anda menggunakan penangkapan kesalahan rumit: misalnya

var a;

a == null; // This is true
a == undefined; // This is true;
a === undefined; // This is true;

Namun, jika Anda sengaja menetapkan nilainya null, kesetaraan ketat dengan undefinedgagal, sehingga memungkinkan Anda untuk membedakan nulldan undefinednilainya:

var b = null;
b == null; // This is true
b == undefined; // This is true;
b === undefined; // This is false;

Lihatlah referensi di sini alih-alih mengandalkan orang-orang dengan acuh tak acuh mengatakan sampah seperti "Singkatnya, undefined adalah kekacauan spesifik JavaScript, yang membingungkan semua orang". Hanya karena Anda bingung, itu tidak berarti bahwa itu berantakan.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

Perilaku ini juga tidak spesifik untuk JavaScript dan melengkapi konsep umum yang hasil boolean bisa true, false, tidak diketahui ( null), tidak ada nilai ( undefined), atau sesuatu yang tidak beres ( error).

http://en.wikipedia.org/wiki/Undefined_value

Todd
sumber
Dan masih nullakan bekerja dengan baik. a == nulladalah truekarena jenis Javascript paksaan.
sleepwalkerfx
11

Cara terbaik untuk memeriksa nilai null adalah

if ( testVar !== null )
{
    // do action here
}

dan untuk yang tidak terdefinisi

if ( testVar !== undefined )
{
    // do action here
}

Anda dapat menetapkan tersedia dengan undefined.

testVar = undefined;
//typeof(testVar) will be equal to undefined.
rahul
sumber
1
Cara terbaik untuk memeriksa nilai null adalah dengan menggunakan !==, bukan!=
MBO
6

YA, Anda bisa, karena tidak terdefinisi didefinisikan sebagai tidak terdefinisi.

console.log(
   /*global.*/undefined === window['undefined'] &&
   /*global.*/undefined === (function(){})() &&
   window['undefined']  === (function(){})()
) //true

kasus Anda:

test("value1", undefined, "value2")

Anda juga dapat membuat variabel tidak terdefinisi sendiri:

Object.defineProperty(this, 'u', {value : undefined});
console.log(u); //undefined

sumber
5

Untuk menjawab pertanyaan pertama Anda, operator yang tidak ( !) akan memaksa apa pun yang diberikan menjadi nilai boolean. Jadi null, 0, false, NaNdan ""(string kosong) akan semua muncul palsu.

Skilldrick
sumber
Dan juga string kosong dan NaN (Bukan angka)
MBO
undefinedtidak akan muncul sebagai false, ia akan melempar kesalahan 'tidak didefinisikan'.
Tatu Ulmanen
Tatu Ulmanen: tidak benar. if (undefined) {/* Do stuff*/}tidak akan memberikan kesalahan, karena undefinedada sebagai properti dari objek global. Apa yang akan memberikan kesalahan adalah sesuatu sepertiif (someUndeclaredVariable) {/* Do stuff*/}
Tim Down
2

JavaScript, cara mengatur variabel menjadi tidak terdefinisi pada commandline:

Setel variabel menjadi tidak terdefinisi di jsterminal baris perintah javascript yang disertakan dengan Java pada Ubuntu 12.10.

el@defiant ~ $ js

js> typeof boo
"undefined"

js> boo
typein:2: ReferenceError: boo is not defined

js> boo=5
5

js> typeof boo
"number"

js> delete(boo)
true

js> typeof boo
"undefined"

js> boo
typein:7: ReferenceError: boo is not defined

Jika Anda mengatur variabel untuk tidak terdefinisi dalam javascript:

Letakkan ini di myjs.html:

<html>
<body>
    <script type="text/JavaScript">
        document.write("aliens: " + aliens);
        document.write("typeof aliens: " + (typeof aliens));
        var aliens = "scramble the nimitz";
        document.write("found some aliens: " + (typeof aliens));
        document.write("not sayings its aliens but... " + aliens);
        aliens = undefined;
        document.write("aliens deleted");
        document.write("typeof aliens: " + (typeof aliens));
        document.write("you sure they are gone? " + aliens);
    </script>
</body>
</html>

Mencetak ini:

aliens: undefined
typeof aliens: undefined
found some aliens: string
not sayings its aliens but... scramble the nimitz
aliens deleted
typeof aliens: undefined
you sure they are gone? undefined

PERINGATAN! Saat mengatur variabel Anda ke undefined Anda mengatur variabel Anda ke variabel lain. Jika beberapa orang licik berjalan undefined = 'rm -rf /';maka setiap kali Anda mengatur variabel Anda ke tidak terdefinisi, Anda akan menerima nilai itu.

Anda mungkin bertanya-tanya bagaimana saya bisa menampilkan nilai alien yang tidak ditentukan di awal dan membuatnya tetap berjalan. Itu karena pengangkatan javascript: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

Eric Leschinski
sumber
2

Coba ini:

// found on UglifyJS
variable = void 0;
Cqq Cqq
sumber
0

Untuk if (something)dan if (!something)biasanya digunakan untuk memeriksa apakah ada sesuatu yang didefinisikan atau tidak. Sebagai contoh:

if (document.getElementById)

Pengidentifikasi dikonversi ke nilai boolean, jadi undefineddiartikan sebagai false. Tentu saja ada nilai-nilai lain (seperti 0 dan '') yang juga ditafsirkan sebagaifalse , tetapi salah satu pengidentifikasi tidak boleh memiliki nilai seperti itu atau Anda senang memperlakukan nilai seperti itu sama dengan yang tidak terdefinisi.

Javascript memiliki deleteoperator yang dapat digunakan untuk menghapus anggota suatu objek. Bergantung pada ruang lingkup variabel (yaitu apakah itu global atau tidak) Anda dapat menghapusnya agar tidak terdefinisi.

Tidak ada undefinedkata kunci yang dapat Anda gunakan sebagai literal yang tidak terdefinisi. Anda bisa menghilangkan parameter dalam panggilan fungsi untuk membuatnya tidak terdefinisi, tetapi itu hanya bisa digunakan dengan mengirimkan lebih sedikit parameter ke fungsi, Anda tidak bisa menghilangkan parameter di tengah.

Guffa
sumber
0

Hanya untuk bersenang-senang, inilah cara yang cukup aman untuk menetapkan "tidak ditugaskan" ke suatu variabel. Agar tabrakan ini terjadi, seseorang harus menambahkan prototipe untuk Object dengan nama yang persis sama dengan string yang dihasilkan secara acak. Saya yakin generator string acak dapat ditingkatkan, tetapi saya hanya mengambil satu dari pertanyaan ini: Hasilkan string / karakter acak dalam JavaScript

Ini bekerja dengan membuat objek baru dan mencoba mengakses properti di atasnya dengan nama yang dihasilkan secara acak, yang kita asumsikan tidak akan ada dan karenanya akan memiliki nilai yang tidak terdefinisi.

function GenerateRandomString() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 50; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var myVar = {}[GenerateRandomString()];
rans
sumber