Bir javascript işlevinden "tanımsız" veya "boş" döndürmek daha mı iyidir?


99

Yazdığım ve temelde şuna benzeyen bir işlevim var:

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;
}

Soru: Burada "boş" döndürmek daha iyi olur mu?

İstediğimi geri verebilirim - belli ki ... Kullanılacak en iyi şeyin ne olduğundan emin değildim.

Bu işlevi çağıran kod, tanımsız ile nasıl başa çıkılacağını bilir (aslında bir şeyler korkunç bir şekilde ters gitmedikçe asla gerçekten olmayacak)

Bu soruyu sormamın nedeni, bir yerde "Tanımlanmamış değişkenlere atama" gibi bir şey duymuş olmamdır - bu, hata ayıklamayı zorlaştıracaktır. Yani, nullgeri döndüğünü görebildiğim gerçeği bana geri dönüşün işe yaradığını söylüyor - ama temelde benzer şekilde çalışıyor undefined.


Dokümantasyon:

Mozilla Docs sorumu cevaplamadı ... google da cevap vermedi: \

Bu SO Sorusu - burada anlamaya çalıştığım şey için çok genişti.


1
bu SO Soru cevabı değil mi?
warkentien2

8
Bence geri dön null. undefinedJavaScript'in kendisine bırakın . Ancak, "daha iyi" diye bir şey yoktur, bu yüzden bu bir görüş meselesidir.
Felix Kling

@ warkentien2 Teşekkürler, bu yardımcı oldu - ancak bir alıcı işlevinden dönmek için burada konvansiyonun ne olduğu konusunda hala emin değilim.
Jeremy Iglehart

1
null"İstediğiniz şeyin uygun bir değeri yok" ve "Ne istediğinizi bulamıyorum" şeklinde okudum undefined.
Marty

@ warkentien2 bu soru ve cevabımda bağladığım soru birbiriyle ilişkili, ancak ikisi de aralarındaki farkın ne olduğunu ve birini veya diğerini dönüş değeri olarak ne zaman kullanacağını soruyor gibi görünüyor .
chiliNUT

Yanıtlar:


38

En iyi yol olmadığını iddia edeceğim ve hatta standart işlevler bazen birini veya diğerini seçer.

Örneğin:

  • [[Prototip]]

    Sıradan nesneler, hangi nesneden miras alacaklarını belirleyen bir [[Prototip]] dahili yuvaya sahiptir. Elbette, bir nesnenin diğerinden miras almadığını söylemenin bir yolu olmalıdır. Bu durumda "böyle bir nesne yok" kullanılarak temsil edilir null.

  • Object.getOwnPropertyDescriptor

    Bir özellik tanımlayıcı, yani bir özelliği tanımlayan bir nesne (örneğin değer, yazılabilirlik, numaralandırılabilirlik ve yapılandırılabilirlik) döndürmesi beklenir. Ancak mülk mevcut olmayabilir. Bu durumda "böyle bir özellik yoktur" kullanılarak temsil edilir undefined.

  • document.getElementById

    Verilen kimliğe sahip öğeyi döndürmesi bekleniyor. Ancak, bu kimliğe sahip hiçbir öğe olmayabilir. Bu durumda "böyle bir öğe yok" kullanılarak temsil edilir null.

Bu yüzden, tercih ettiğiniz veya özel durumunuz için daha mantıklı olduğunu düşündüğünüz şeyi seçin.


3
bunu okuduktan sonra void 0, bu cevabın gelecekteki izleyicileri için tekniği önermeye karar verdim . Ayrıca amacınızı daha net hale getirmek için bazı kodlar ekledim. Cevabınız için teşekkür ederim!
Jeremy Iglehart

115

Tanımsız, genellikle (henüz) bir değer atanmamış bir şeyi ifade eder. Null, kesinlikle değeri olmayan bir şeyi ifade eder. Bu durumda, bir boş değer döndürmenizi tavsiye ederim. Belirtilen dönüş değeri olmayan bir işlevin örtük olarak tanımsız döndürdüğünü unutmayın.

ECMAScript2015 spesifikasyonundan

4.3.10 tanımsız değer

bir değişkene bir değer atanmadığında kullanılan ilkel değer

4.3.12 boş değer

Herhangi bir nesne değerinin kasıtlı yokluğunu temsil eden ilkel değer

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

Daha fazla okuma:

JavaScript'te ne zaman boş veya tanımsız kullanılır?


1
Evet, tanımsız, bir değişkene bir değer atanmadığında kullanılan değerdir. Neden tam olarak bu, bir işlevde tanımsız döndürmemeniz gerektiği anlamına gelir?
Oriol

1
@Oriol, aklımda, bir void işlevi undefined döndürdüğünden, bu o türden işlevler için ayrılmış bir değerdir, böylece bir işlevin dönüş değerini işlerken, null bana null döndürmeye karar verdiğini söylerken, undefined bana bunu söyler ya tanımsız dönmeye karar verdi ya da hiçbir şey iade etmemeye karar verdi, ama hangisi olduğunu kesin olarak bilmiyorum. Dahası, eğer yapıyorsam var x=someFunc();, kasıtlı olarak xa değerini veriyorum ve ona bir değer atanmadığını (veya atanmadığını) gösteren herhangi bir testi geçmemeyi tercih ederim. Just
imho

Kabul edilen cevap bu olmalıdır. Spesifikasyonda bu şekilde kullanılması amaçlanmıştı
Zinc,

1
Ben o şekilde okumuyorum. Şöyle okudum: Bir değişken tanımlar ancak onu başlatmazsanız, bunun yerine başlangıç ​​değeri undefined olacaktır. Null, programcı tarafından kasıtlı olarak bir değişkenin boş olduğunu belirtmek için kullanılmalıdır. IMHO undefined asla programcı tarafından bir değişkene atanmamalıdır, onu kullanmak için js motoruna bırakın. "Nesne" değeri terimi yanıltıcıdır, çünkü JS'de ilkeller bile otomatik kutudan dolayı çoğunlukla nesneler gibi davranırlar
chiliNUT

1
Evet, mantıklı. Dürüst olmak gerekirse, bir tanesine bağlı nullkaldığınız sürece birini diğerinin üzerine kullanmayı umursamıyorum (buna daha alışkınım ), ancak değerin olmadığını gösteren 2 değere sahip olmak ("tür" ne olursa olsun) her zaman kafa karıştırıcı
Sergio Rosas

39

İkisi arasında kişisel fikrimi seçme yöntemimi size vereceğim.

Benim basit sorum şu: Başka bir girdi / durum / bağlam verildiğinde değer bir şeye tanımlanabilir mi?

Cevap evet ise, o zaman nullbaşka kullanın undefined. Daha genel olarak, bir nesneyi döndüren herhangi bir işlev null, amaçlanan nesne mevcut olmadığında dönmelidir . Çünkü başka bir girdi / durum / bağlam verildiğinde var olabilir.

nullbelirli bir girdi / durum / bağlam için değerin yokluğunu temsil eder . Örtük olarak, değer kavramının kendinizin uygulamanız bağlamında var olduğu, ancak bulunmayabileceği anlamına gelir. Örneğinizde bir sonraki kart kavramı mevcuttur, ancak kartın kendisi mevcut olmayabilir. nullkullanılmalıdır.

undefinedUygulamanızın bağlamında bu değerin anlamının yokluğunu dolaylı olarak temsil eder . Örneğin, userbelirli bir özellik kümesine sahip bir nesneyi işlersem ve özelliğe erişmeye çalışırsam pikatchu. Bu özelliğin değeri olarak ayarlanmalıdır undefinedçünkü benim bağlamımda böyle bir özelliğe sahip olmak mantıklı değil.


1
Bu bana çok gerçek geliyor. İşlevsel bir programcı gibi düşünürken nullyan etkileri olan işlevler geri dönerken IMO saf işlevleri geri dönmelidir undefined.
Jake

4

undefinedatamanız gereken bir şey değil. Dışında başka bir şey iade etmeyi düşünebilirsiniz undefined. Sizin durumunuzda, hiçbir şey iade etmeseniz bile, sonuç undefinedzaten olacaktır . Bu yüzden, nullonun yerine gitmeyi öneririm .

Bu örneği düşünün,

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

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

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

Yukarıdaki örnek a === b, yani undefined. Aradaki fark, 1 ifade yürütmesini kaydetmenizdir.


@Oriol Demek istediğim, atanmak undefinedzorunda değil. Değer içermeyen tüm bildirilen değişkenler zaten undefined.
choz

@choz & @Oriol - daha önce @chiliNUT tarafından belirtildiği gibi "Belirtilen dönüş değeri olmayan bir işlevin örtük olarak tanımsız döndürdüğüne dikkat edin." - bu doğrudur çünkü (function(){ /* code */ })()bir konsolda null döndürür.
Jeremy Iglehart

@JeremyIglehart Bu kod aslında hiçbir şey döndürmüyor. Ve başka, undefinedbenim chrome ve firefox konsolumda veriyor .
choz

Tamam ne demek istediğini anlamadım Evet, açık bir şekilde herhangi bir şey döndürmezseniz, undefined örtük olarak döndürülür. Ama bu neden önemli?
Oriol

1
@Oriol, @ choz'un söylemeye çalıştığını düşünüyorum (bu soruda da bahsedildiği gibi), eğer undefinedbaşka bir şey daha önce dönmezse geri dönmek istersem - buna ihtiyacım yok çünkü fonksiyonun varsayılan davranışı hiçbir şey geri dönmezseniz, tanımsız olarak geri döner - sadece bunun gerekli olmadığını söylüyorlar. Dahası ... Null döndüren yerleşik alıcı işlevleri hakkında söylediklerinizi beğendim. Lütfen bu etkiye cevabınızı gönderin, ben de kabul edeceğim.
Jeremy Iglehart

3

Döndürülen değerle ne yapmanız gerektiğine bağlıdır.

typeof null bir nesne döndürür. bu nesnenin değeri tanımsız

typeof tanımsız döndürür undefined


Şahsen ben genellikle null kullanıyorum.
Dan

4
"bu nesnenin tanımlanmamış bir değeri var" Hayır değil ve bir nesne değil, Boş. typeofbir değerin doğru veri türünü döndürmesi gerekmez, veri türlerini etiketlerle eşleyen ve karşılık gelen etiketi döndüren bir haritaya sahiptir.
Felix Kling

Güvenme typeof, adını rağmen bir değerin türünü söylemez.
Oriol

3

İşte undefineddaha mantıklı olan bir örnek null:

JSON.parseİstisnasını şuna dönüştüren bir sarmalayıcı işlevi kullanıyorum 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
}

Bunun nullJSON'da geçerli olduğunu , ancak undefinedolmadığını unutmayın.


Orada ne yaptığını anlıyorum - ve yanıldığını söyleyemem - çünkü bir anlamda bunu burada yapabileceğini düşünüyorum ve bu iyi olur. Daha çok sevdiğim bu işlemi yapmak için kullandığım farklı bir kalıbım var çünkü sonrasında bir "doğrulama" adımı yapıyorum. Bunun, değeri döndürmekle onaylanmaya başladığını hissediyorum. İşte benim işim: let getStringOrJSON = value => { try { value = JSON.parse(value); } catch(e) { return value; } return value; };. Şimdi, eminim iki dönüş farklı şekilde ele alınabilir ve JS golf yarışmasını kazanamayabilir. İşe yarıyor.
Jeremy Iglehart

2

Bu durumda nulliade edilmesi gerektiğini iddia ediyorum .

Sonra bir görüş teorik bilgisayar bilimi açısından soru düşünürsek tanımsız belirtmek için kullanılır olmayan sonlandırma / olmayan Hesaplanabilirlik (tanımlanmamış bir nokta için yani yer tutucu xa kısmi fonksiyonu f genellikle yazılır f(x) = ⊥).

getNextCardancak bir sonraki kartı hesaplayabilecek (eğer varsa) ve ayrıca bir sonraki kartın olup olmadığını hesaplayabilecek gibi görünüyor. Başka bir deyişle, işlevidir toplam her giriş için sona beri.

Bununla birlikte, anlamlı sonucu olmayan özel bir değer sinyali sonlandırması (yani "bu giriş için geri dönebileceğim bir kart yok") gereklidir ve bu benim için nulldeğil undefined.


NOTLAR:

Bu bağımsız değişken için bazı diğer yazılı dillerde ve anlamlı sonuç olmadan sonlandırmanın bir seçenek türü (bazen null atanabilir tür olarak da adlandırılır) kullanılarak ifade edildiği yerlerde bazı destek görebilirsiniz . Bu için bir örnek Belki de Haskell .

Öte yandan, elbette undefinedJavaScript'te gerçekten ne anlama geldiğini bilmiyoruz . Yani, tanımsız ile benzetme biraz zayıf. Dahası, her zaman toplam işlevlerle çalışmak istediğimizden, bu "asla undefinedbir işlevden dönme" demek anlamına gelir . undefinedAyarlanmamış özellikler / değişkenlerin kullanımını sınırlayacağı için bu biraz katı görünüyor .

Sonunda, kişisel tercihim asla geri dönebileceğim bir undefinedyere geri dönmemek nullve bunun daha iyi bir kodlama kuralı olduğunu da savunuyorum (çünkü diğer şeylerin yanı sıra x !== nulldaha kısa typeof x !== 'undefined').


1

İlk cevap doğru. Teorik olarak farklı anlamları var. Ancak hangisini alacağınız her zaman net değildir.

Tamamen öznel bir şey olduğunu düşünmeme rağmen, gelişimimde null kullanma eğilimindeyim.

Bunu çoğunlukla şu sebeple kullanıyorum:

  1. Eski tarayıcılarda tanımsız değişkenin üzerine yazılabilir, bu yüzden onu döndürmek biraz daha karmaşıktır. Aynı sorun sizi typeof var === 'undefined'işlev sonuçları alırken kullanmaya zorlar . bağlantı

  2. Diğer diller null'u yaygın olarak kullanma eğilimindedir, çoğunda tanımsız bile yoktur (örneğin php). Bu, diller arasında hızlı geçiş yaparken bana bir tür tutarlılık sağlıyor.


1

Bence ne kullanılacağı çok tartışmalı. Anlamsal olarak olabildiğince doğru olan kodu tercih ederim, bu yüzden undefinedbu durumda uygun olduğunu düşünüyorum .

nullAtamaları "sıfıra ayarlanmış bir değişken" olarak düşünüyorum . Bu, undefined"bu şey hiç orada değil" anlamının tersidir.

Önceki bir cevabın işaret ettiği gibi, geri dönmenin undefinedsorunları vardır ve bunun sizi rahatsız edip etmediği tamamen size bağlıdır. Beni rahatsız etmez.


2
Ancak anlamı "bu şey hiç yok" a daha yakın olsa da document.getElementById('iDoNotExist')geri döner null. Standart yöntemler bunu yapıyorsa, neden OP olmasın?
Oriol

@Oriol Aslında en çok mantığınızı seviyorum. Lütfen bu etkiye bir cevap gönderin, kabul edeceğim. (Gerekirse birkaç düzenleme bile ekleyebilirim)
Jeremy Iglehart

Yah @Oriol, bu yüzden Q / A sitelerinde bile tartışmalardan zevk alıyorum. Karşı örnekler almak gerçekten çok iyi. Ve sen iyi bir tane sağladın.
Ryan Laboucane

-2

Deneyimlerime göre kişisel görüşüm, kodunuzu çökertmek istemiyorsanız, tanımsız ve boş kullanmayın. En azından şahsen bundan kaçınırdım. Javascript'te tanımsız olarak dönen ve kullanmamız gereken pek çok işlev var. Ancak kodunuzu tasarlarken onu kullanmayın. Her zaman "false"en azından bir şeyi iade etmek önemlidir . Örneğin bir diziniz varsa ve bunun üzerine eşleme yaparsanız. Geri dönmek [undefined, undefined.....]ya da adil olmak iyi değil undefined. Orijinal dizinin türünü korumanız daha iyi olur. Misal:

 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

Fikir bu. Her zaman bundan kaçınmaya çalışıyorum. Çünkü bir nullveya undefinedkodunuzu kolayca çökertebilir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.