Apakah lebih baik mengembalikan `undefined` atau` null` dari fungsi javascript?

98

Saya memiliki fungsi yang telah saya tulis yang pada dasarnya terlihat seperti ini:

function getNextCard(searchTerms) {
  // Setup Some Variables

  // Do a bunch of logic to pick the next card based on termed passed through what I'll call here as 'searchTerms' all of this logic is omitted because it's not important for my question.
  // ...

  // If we find a next card to give, than give it
  if (nextCardFound)
    return nextCardFound;

  // Otherwise - I'm returning undefined
  return undefined;
}

Pertanyaan: Apakah lebih baik mengembalikan "null" di sini?

Saya dapat mengembalikan apa pun yang saya inginkan - tentu saja ... Saya hanya tidak yakin apa yang terbaik untuk digunakan.

Kode yang memanggil fungsi ini tahu bagaimana menangani undefined (sebenarnya tidak akan pernah benar-benar terjadi kecuali ada yang tidak beres)

Alasan saya menanyakan pertanyaan ini adalah karena saya mendengar sesuatu yang terdengar seperti "Jangan tetapkan tidak terdefinisi ke variabel" atau sesuatu - yang akan mempersulit proses debug. Jadi, fakta bahwa saya dapat melihat yang nulldikirimkan kembali memberi tahu saya bahwa pengembaliannya berfungsi - tetapi pada dasarnya berfungsi mirip dengan undefined.


Dokumentasi:

Mozilla Docs Tidak menjawab pertanyaan saya ... google juga tidak: \

Pertanyaan SO ini - terlalu luas untuk apa yang saya coba cari tahu di sini.

Jeremy Iglehart
sumber
1
bukankah pertanyaan SO ini menjawab?
warkentien2
8
Menurut pendapat saya, kembali null . Tinggalkan undefinedJavaScript itu sendiri. Namun, tidak ada yang "lebih baik" jadi ini masalah opini.
Felix Kling
@ warkentien2 Terima kasih, ini sangat membantu - tapi saya masih belum jelas tentang apa konvensi di sini untuk kembali dari fungsi pengambil.
Jeremy Iglehart
1
Saya membaca nullsebagai "tidak ada nilai yang sesuai untuk apa yang Anda minta" dan undefinedsebagai "Saya tidak dapat menjawab apa yang Anda minta".
Marty
@ warkentien2 pertanyaan itu, dan yang saya tautkan dalam jawaban saya, terkait, tetapi keduanya tampaknya menanyakan apa perbedaan di antara mereka dan bukan kapan harus menggunakan satu atau yang lain sebagai nilai pengembalian.
cabaiNUT

Jawaban:

37

Saya berpendapat tidak ada cara terbaik, dan bahkan fungsi standar terkadang memilih satu atau yang lain.

Sebagai contoh:

  • [[Prototipe]]

    Objek biasa memiliki slot internal [[Prototipe]], yang menentukan dari objek lain mana mereka mewarisi. Tentu saja, harus ada cara untuk mengatakan bahwa suatu objek tidak mewarisi dari yang lain. Dalam kasus ini, "tidak ada objek seperti itu" diwakili menggunakan null.

  • Object.getOwnPropertyDescriptor

    Diharapkan untuk mengembalikan deskriptor properti, yaitu objek yang mendeskripsikan properti (misalnya nilai, kemampuan menulis, enumerabilitas, dan konfigurasi). Namun, properti tersebut mungkin tidak ada. Dalam kasus ini, "tidak ada properti seperti itu" diwakili menggunakan undefined.

  • document.getElementById

    Diharapkan untuk mengembalikan elemen dengan ID yang diberikan. Namun, mungkin tidak ada elemen dengan ID tersebut. Dalam kasus ini, "tidak ada elemen seperti itu" diwakili menggunakan null.

Jadi pilih saja apa pun yang Anda suka atau anggap lebih masuk akal untuk kasus spesifik Anda.

Oriol
sumber
3
setelah membaca ini saya memutuskan untuk menyarankan void 0teknik ini untuk pemirsa selanjutnya dari jawaban ini. Saya juga menambahkan beberapa kode untuk mencoba dan membuat maksud Anda lebih jelas. Terima kasih atas jawaban Anda!
Jeremy Iglehart
114

Undefined biasanya mengacu pada sesuatu yang belum diberi nilai (yet). Null mengacu pada sesuatu yang secara definitif tidak memiliki nilai. Dalam hal ini, saya akan merekomendasikan mengembalikan null. Perhatikan bahwa fungsi tanpa nilai kembalian yang ditentukan secara implisit mengembalikan tidak terdefinisi.

Dari spesifikasi ECMAScript2015

4.3.10 nilai tidak ditentukan

nilai primitif digunakan ketika variabel belum diberi nilai

4.3.12 nilai nol

nilai primitif yang mewakili ketidakhadiran yang disengaja dari nilai objek apa pun

http://www.ecma-international.org/ecma-262/6.0/#sec-terms-and-definitions-undefined-type

Bacaan lebih lanjut:

Kapan null atau undefined digunakan dalam JavaScript?

cabai
sumber
1
Ya, tidak ditentukan adalah nilai yang digunakan saat variabel belum diberi nilai. Mengapa tepatnya hal itu menyiratkan bahwa Anda tidak boleh mengembalikan tidak terdefinisi dalam suatu fungsi?
Oriol
1
@Oriol, dalam pikiran saya, karena fungsi void mengembalikan tidak terdefinisi, itu adalah nilai yang dicadangkan untuk fungsi jenis itu, sehingga ketika menangani nilai kembalian suatu fungsi, null memberi tahu saya bahwa ia memutuskan untuk mengembalikan null, sedangkan undefined memberi tahu saya baik memutuskan untuk mengembalikan tidak ditentukan, atau memutuskan untuk tidak mengembalikan apa pun, tetapi saya tidak tahu pasti yang mana. Selanjutnya, jika saya melakukannya var x=someFunc();, saya dengan sengaja menetapkan nilai xa, dan lebih suka tidak lulus tes apa pun yang menunjukkan itu belum (atau mungkin belum) diberi nilai. Just imho
chiliNUT
Ini harus menjadi jawaban yang diterima. Inilah yang dimaksudkan untuk digunakan dalam spesifikasi
Seng
1
Saya tidak membacanya seperti itu. Saya membacanya sebagai: Jika Anda mendefinisikan variabel tetapi tidak menginisialisasinya, itu malah akan memiliki nilai awal tidak terdefinisi. Null harus digunakan oleh programmer untuk secara sengaja menunjukkan bahwa variabel kosong. IMHO undefined tidak boleh ditugaskan ke variabel oleh programmer, serahkan pada mesin js untuk menggunakannya. Nilai istilah "objek" menyesatkan, karena di JS bahkan primitif berperilaku seperti objek untuk sebagian besar karena autoboxing
chiliNUT
1
Ya, itu masuk akal. Agar adil, saya tidak keberatan menggunakan yang satu di atas yang lain (meskipun saya lebih terbiasa null) selama Anda tetap menggunakan satu, tetapi memiliki 2 nilai untuk menunjukkan tidak adanya nilai (apa pun "tipe") selalu membingungkan
Sergio Rosas
39

Saya akan memberi Anda cara pribadi saya untuk memilih di antara keduanya.

Pertanyaan sederhana saya adalah: dapatkah nilai, dengan masukan / status / konteks lain didefinisikan sebagai sesuatu?

Jika jawabannya iya maka gunakan nullelse use undefined. Secara lebih umum, fungsi apa pun yang mengembalikan objek harus dikembalikan nullketika objek yang dimaksud tidak ada. Karena itu bisa ada diberi masukan / keadaan / konteks lain.

nullmewakili ketiadaan nilai untuk input / status / konteks tertentu. Ini secara implisit berarti bahwa konsep nilai itu sendiri ada dalam konteks aplikasi Anda, tetapi mungkin tidak ada. Dalam contoh Anda, konsep kartu berikutnya ada, tetapi kartu itu sendiri mungkin tidak ada.nullseharusnya digunakan.

undefinedsecara implisit merepresentasikan ketiadaan makna dari nilai tersebut dalam konteks aplikasi Anda. Misalnya, jika saya memanipulasi userobjek dengan sekumpulan properti tertentu dan saya mencoba mengakses properti pikatchu. Nilai properti ini harus disetel ke undefinedkarena dalam konteks saya, tidak masuk akal untuk memiliki properti seperti itu.

ngryman
sumber
1
Ini sangat nyata bagiku. Fungsi murni IMO harus kembali null, sedangkan fungsi dengan efek samping harus kembali undefined, ketika berpikir seperti programmer fungsional.
Jake
4

undefinedbukanlah sesuatu yang harus Anda tetapkan. Anda mungkin ingin mempertimbangkan untuk mengembalikan sesuatu selain undefined. Dalam kasus Anda, bahkan jika Anda tidak mengembalikan apa pun, hasilnya akan undefinedsudah ada. Jadi, saya sarankan untuk pergi nullsaja.

Pertimbangkan contoh ini,

function getSomething() {
     // .. do something
     return undefined;
}

function doSomething() {
     // .. I'm not gonna return anything.
}

var a = getSomething();
var b = doSomething();

Hasil sampel di atas a === b, yaitu undefined. Perbedaannya adalah Anda menyimpan 1 eksekusi pernyataan.

choz
sumber
@Oriol Maksudku, undefinedtidak harus ditugaskan. Semua variabel yang dideklarasikan tanpa nilai sudah undefined.
choz
@choz & @Oriol - seperti yang disebutkan sebelumnya oleh @chiliNUT "Perhatikan bahwa fungsi tanpa nilai kembalian yang ditentukan secara implisit mengembalikan tidak terdefinisi." - ini benar karena (function(){ /* code */ })()mengembalikan null di konsol.
Jeremy Iglehart
@JeremyIglehart Kode itu sebenarnya tidak mengembalikan apa pun. Dan lainnya, itu memberi undefinedpada konsol chrome dan firefox saya.
choz
Oke, saya tidak mengerti maksud Anda. Ya, jika Anda tidak mengembalikan apapun secara eksplisit, undefined akan dikembalikan secara implisit. Tapi mengapa itu penting?
Oriol
1
@Oriol, saya pikir apa yang @choz coba katakan (karena beberapa orang lain juga menyebutkan tentang pertanyaan ini) bahwa jika saya ingin mengembalikan undefinedjika sesuatu yang lain tidak kembali lebih awal - saya tidak perlu melakukannya karena perilaku default fungsi jika Anda tidak mengembalikan apa pun berarti mengembalikan tidak ditentukan - mereka hanya mengatakan bahwa ini tidak diperlukan. Selanjutnya ... Saya suka apa yang Anda katakan tentang fungsi getter built-in yang mengembalikan null. Silakan posting jawaban Anda untuk efek itu dan saya akan menerimanya.
Jeremy Iglehart
3

Tergantung pada apa yang perlu Anda lakukan dengan nilai yang dikembalikan.

typeof null mengembalikan sebuah objek. objek tersebut memiliki nilai tidak terdefinisi

typeof undefined return undefined

Dan
sumber
Secara pribadi saya biasanya menggunakan null.
Dan
4
"objek itu memiliki nilai tidak terdefinisi" Tidak, bukan dan itu bukan objek, itu Null. typeoftidak selalu mengembalikan tipe data sebenarnya dari suatu nilai, ia memiliki peta yang memetakan tipe data ke label dan mengembalikan label yang sesuai.
Felix Kling
Jangan percaya typeof, meskipun namanya tidak memberi tahu jenis nilai.
Oriol
2

Berikut adalah contoh di mana undefinedlebih masuk akal daripadanull :

Saya menggunakan fungsi pembungkus untuk JSON.parseitu mengubah pengecualiannya menjadi undefined:

// parses s as JSON if possible and returns undefined otherwise
// return undefined iff s is not a string or not parseable as JSON; undefined is not a valid JSON value https://stackoverflow.com/a/14946821/524504
function JSON_parse_or_undefined(s) {
    if ("string" !== typeof s) return undefined

    try {
        const p = JSON.parse(s)
        return p
    } catch (x){}

    return undefined
}

Perhatikan bahwa nullini valid di JSON sedangkan undefinedtidak.

masterxilo
sumber
Saya melihat apa yang Anda lakukan di sana - dan saya tidak bisa mengatakan Anda salah - karena dalam arti tertentu saya pikir Anda bisa melakukan ini di sini dan itu akan baik-baik saja. Saya memiliki pola berbeda yang saya gunakan untuk melakukan operasi ini yang lebih saya sukai karena saya melakukan langkah "validasi" setelahnya. Saya merasa ini mendapatkan validasi dicampur dengan mengembalikan nilai. Berikut adalah apa yang saya lakukan: let getStringOrJSON = value => { try { value = JSON.parse(value); } catch(e) { return value; } return value; };. Sekarang, saya yakin dua pengembalian dapat ditangani secara berbeda, dan mungkin tidak memenangkan kompetisi golf JS. Berhasil.
Jeremy Iglehart
1

Jawaban pertama benar. Mereka memiliki arti yang berbeda secara teoritis. Namun tidak selalu jelas mana yang harus diambil.

Saya cenderung menggunakan nol dalam perkembangan saya meskipun saya pikir itu sepenuhnya subjektif.

Saya menggunakannya terutama karena:

  1. variabel tidak terdefinisi mungkin ditimpa di browser lama jadi mengembalikannya sedikit lebih rumit. Masalah yang sama ini memaksa Anda untuk menggunakan typeof var === 'undefined'saat mendapatkan hasil fungsi. tautan

  2. Bahasa lain cenderung menggunakan null secara luas, banyak di antaranya bahkan tidak memiliki definisi (php misalnya). Itu memberi saya konsistensi saat beralih antar bahasa dengan cepat.

Maciej Paprocki
sumber
1

Saya pikir sangat diperdebatkan apa yang harus digunakan. Saya lebih suka kode yang semantik seakurat mungkin, jadi menurut saya undefinedsesuai dalam kasus ini.

Saya memikirkan nulltugas sebagai arti "variabel yang tidak ada artinya". Ini berlawanan dengan undefinedarti "hal ini tidak ada sama sekali"

Seperti yang ditunjukkan oleh jawaban sebelumnya, kembali undefinedmemiliki masalah, dan sepenuhnya terserah Anda apakah itu mengganggu Anda. Itu tidak akan mengganggu saya.

Ryan Laboucane
sumber
2
Tetapi document.getElementById('iDoNotExist')kembali null, meskipun artinya lebih dekat dengan "hal ini tidak ada sama sekali". Jika metode standar melakukannya, mengapa tidak OP?
Oriol
@Oriol Aku sebenarnya paling suka alasanmu. Silakan posting jawaban untuk efek ini dan saya akan menerimanya. (Saya bahkan mungkin menambahkan beberapa pengeditan jika perlu)
Jeremy Iglehart
Yah @Oriol, inilah mengapa saya benar-benar menikmati debat, bahkan di situs Tanya Jawab. Sangat bagus untuk mendapatkan contoh kontra. Dan Anda telah memberikan yang bagus.
Ryan Laboucane
1

Saya berpendapat bahwa dalam kasus ini, nullharus dikembalikan.

Jika Anda mempertimbangkan pertanyaan dari sudut pandang ilmu komputer teoretis maka undefined digunakan untuk menunjukkan non-termination / non-computability (yaitu placeholder untuk titik tak terdefinisi xdari fungsi parsial f yang sering ditulis f(x) = ⊥).

getNextCardnamun tampaknya dapat menghitung kartu berikutnya (jika ada) dan juga dapat menghitung jika tidak ada kartu berikutnya. Dengan kata lain, fungsinya total karena berhenti untuk setiap masukan.

Karena itu, penghentian pensinyalan nilai khusus tanpa hasil yang berarti (yaitu "tidak ada kartu yang dapat saya kembalikan untuk masukan ini") diperlukan dan ini untuk saya nulltidak undefined.


CATATAN:

Anda dapat melihat beberapa dukungan untuk argumen ini dalam beberapa bahasa yang diketik lainnya juga di mana penghentian tanpa hasil yang berarti diekspresikan menggunakan tipe opsi (terkadang juga disebut sebagai tipe nullable ). Contohnya adalah Maybe in Haskell .

Di sisi lain, kita tentu tidak tahu apa undefined JavaScript. Jadi, analogi undefined agak renggang. Selain itu, karena kita selalu ingin bekerja dengan fungsi total, ini berarti mengatakan "tidak pernah kembali undefineddari suatu fungsi". Yang tampaknya agak ketat, karena akan membatasi penggunaan undefinedproperti / variabel yang belum disetel.

Pada akhirnya, preferensi pribadi saya adalah tidak pernah kembali ke undefinedtempat saya dapat kembali nulldan saya juga berpendapat bahwa ini adalah konvensi pengkodean yang lebih baik (karena antara lain x !== nulllebih pendek dari typeof x !== 'undefined').

FK82
sumber
-2

Pendapat pribadi saya menurut pengalaman saya adalah jangan gunakan undefined dan null jika Anda tidak ingin merusak kode Anda. Setidaknya saya akan menghindarinya secara pribadi. Ada banyak fungsi di Javascript yang kembali tidak terdefinisi dan ok kita harus menggunakannya. Tetapi ketika Anda mendesain kode Anda, jangan menggunakannya. Penting untuk selalu mengembalikan sesuatu "false"setidaknya. Jika Anda memiliki sebuah array misalnya dan Anda memetakannya. Tidak baik untuk kembali [undefined, undefined.....]atau hanya undefined. Lebih baik jika Anda tetap menggunakan tipe array asli. Contoh:

 const mapper:Map <string[],boolean[]>  
['i', 'dont', 'use', 'null or undefined'] -> [false, true, false, true, false]
or ['', dont, '', '', use] 
or al the stuff above and then filter(v => v)
that will keep all undefined and null out

Itu idenya. Saya mencoba sepanjang waktu untuk menghindarinya. Karena nullatau undefineddapat dengan mudah merusak kode Anda

rubendmatos1985
sumber