Ist es besser, "undefined" oder "null" von einer Javascript-Funktion zurückzugeben?

96

Ich habe eine Funktion, die ich geschrieben habe und die im Grunde so aussieht:

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

Frage: Wäre es besser, hier "null" zurückzugeben?

Ich kann alles zurückgeben, was ich will - offensichtlich ... Ich war mir einfach nicht sicher, was das Beste ist.

Der Code, der diese Funktion aufruft, weiß, wie man mit undefiniert umgeht (es wird tatsächlich nie wirklich passieren, wenn nicht etwas schrecklich schief geht).

Der Grund, warum ich diese Frage stelle, ist, dass ich irgendwo etwas gehört habe, das sich wie "Variablen nicht undefiniert zuweisen" oder so anhörte - dass es das Debuggen erschwert. Die Tatsache, dass ich sehe, dass nulldas zurückgegeben wird, sagt mir, dass die Rückgabe funktioniert - aber im Grunde funktioniert es ähnlich wie undefined.


Dokumentation:

Mozilla Docs hat meine Frage nicht beantwortet ... Google auch nicht: \

Diese SO-Frage war viel zu weit gefasst für das, was ich hier herausfinden möchte.

Jeremy Iglehart
quelle
1
beantwortet diese SO-Frage nicht ?
warkentien2
7
Meiner Meinung nach zurück null. Überlassen Sie undefinedJavaScript. Es gibt jedoch kein "besseres", daher ist dies Ansichtssache.
Felix Kling
@ warkentien2 Danke, das war hilfreich - aber ich bin mir immer noch nicht sicher, wie die Konvention hier ist, um von einer Getter-Funktion zurückzukehren.
Jeremy Iglehart
1
Ich las nullals "es gibt keinen angemessenen Wert für das, wonach Sie fragen" und undefinedals "Ich kann nicht herausfinden, wonach Sie fragen".
Marty
@ warkentien2 Diese Frage und die, die ich in meiner Antwort verlinkt habe, hängen zusammen, aber beide scheinen zu fragen, was der Unterschied zwischen ihnen ist und nicht, wann der eine oder andere als Rückgabewert verwendet werden soll.
ChiliNUT

Antworten:

36

Ich werde argumentieren, dass es keinen besten Weg gibt, und sogar Standardfunktionen wählen manchmal den einen oder anderen.

Beispielsweise:

  • [[Prototyp]]

    Gewöhnliche Objekte haben einen internen Steckplatz, der bestimmt, von welchem ​​anderen Objekt sie erben. Natürlich muss es eine Möglichkeit geben zu sagen, dass ein Objekt von keinem anderen erbt. In diesem Fall wird "es gibt kein solches Objekt" mit dargestellt null.

  • Object.getOwnPropertyDescriptor

    Es wird erwartet, dass ein Eigenschaftsdeskriptor zurückgegeben wird, dh ein Objekt, das eine Eigenschaft beschreibt (z. B. Wert, Schreibbarkeit, Aufzählbarkeit und Konfigurierbarkeit). Die Eigenschaft kann jedoch nicht vorhanden sein. In diesem Fall wird "es gibt keine solche Eigenschaft" mit dargestellt undefined.

  • document.getElementById

    Es wird erwartet, dass das Element mit der angegebenen ID zurückgegeben wird. Möglicherweise ist jedoch kein Element mit dieser ID vorhanden. In diesem Fall wird "es gibt kein solches Element" mit dargestellt null.

Wählen Sie also einfach, was Sie bevorzugen oder was für Ihren speziellen Fall sinnvoller ist.

Oriol
quelle
3
Nachdem ich dies gelesen hatte, beschloss ich, die void 0Technik für zukünftige Betrachter dieser Antwort vorzuschlagen . Ich habe auch Code hinzugefügt, um Ihren Standpunkt klarer zu machen. Vielen Dank für Ihre Antwort!
Jeremy Iglehart
111

Undefiniert bezieht sich normalerweise auf etwas, dem (noch) kein Wert zugewiesen wurde. Null bezieht sich auf etwas, das definitiv keinen Wert hat. In diesem Fall würde ich empfehlen, eine Null zurückzugeben. Beachten Sie, dass eine Funktion ohne angegebenen Rückgabewert implizit undefiniert zurückgibt.

Aus der ECMAScript2015-Spezifikation

4.3.10 undefinierter Wert

primitiver Wert, der verwendet wird, wenn einer Variablen kein Wert zugewiesen wurde

4.3.12 Nullwert

primitiver Wert, der das absichtliche Fehlen eines Objektwerts darstellt

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

Weiterführende Literatur:

Wann wird in JavaScript null oder undefiniert verwendet?

chiliNUT
quelle
1
Ja, undefiniert ist der Wert, der verwendet wird, wenn einer Variablen kein Wert zugewiesen wurde. Warum genau bedeutet das, dass Sie in einer Funktion nicht undefiniert zurückgeben sollten?
Oriol
1
@Oriol, da eine void-Funktion undefiniert zurückgibt, ist dies ein reservierter Wert für Funktionen dieses Typs. Wenn also der Rückgabewert einer Funktion behandelt wird, sagt mir null, dass sie sich entschieden hat, null zurückzugeben, während undefined es mir sagt Entweder entschied man sich, undefiniert zurückzukehren, oder es entschied sich, nichts zurückzugeben, aber ich weiß definitiv nicht, welche. Wenn ich dies tue var x=someFunc();, weise ich absichtlich einen xa-Wert zu und möchte lieber keine Tests bestehen, die darauf hinweisen, dass ihm kein Wert zugewiesen wurde (oder möglicherweise nicht). Nur imho
chiliNUT
Dies sollte die akzeptierte Antwort sein. So sollte es in der Spezifikation verwendet werden
Zink
1
Ich lese es nicht so. Ich habe es so gelesen: Wenn Sie eine Variable definieren, sie aber nicht initialisieren, hat sie stattdessen den Anfangswert undefined. Der Programmierer sollte Null verwenden, um absichtlich anzuzeigen, dass eine Variable leer ist. IMHO undefined sollte niemals vom Programmierer einer Variablen zugewiesen werden. Überlassen Sie dies der js-Engine, um sie zu verwenden. Der Begriff "Objekt" -Wert ist irreführend, da sich in JS sogar die
Grundelemente
1
Ja, das macht Sinn. Um fair zu sein, es macht mir nichts aus, einen über den anderen zu verwenden (obwohl ich es eher gewohnt bin null), solange Sie sich an einen halten, aber 2 Werte zu haben, um anzuzeigen, dass kein Wert vorhanden ist (unabhängig vom "Typ"), ist immer verwirrend
Sergio Rosas
34

Ich werde Ihnen meine persönliche Meinung zur Wahl zwischen beiden geben.

Meine einfache Frage lautet: Könnte der Wert bei einer anderen Eingabe / einem anderen Status / Kontext für etwas definiert werden?

Wenn die Antwort ja ist, verwenden Sie nullelse use undefined. Im Allgemeinen sollte jede Funktion, die ein Objekt zurückgibt, zurückgegeben werden, nullwenn das beabsichtigte Objekt nicht vorhanden ist. Weil es bei einem anderen Eingang / Zustand / Kontext existieren könnte.

nullrepräsentiert das Fehlen eines Wertes für eine gegebene Eingabe / einen gegebenen Zustand / einen gegebenen Kontext. Dies bedeutet implizit, dass das Konzept des Werts selbst im Kontext Ihrer Anwendung existiert, aber möglicherweise nicht vorhanden ist. In Ihrem Beispiel existiert das Konzept einer nächsten Karte, aber die Karte selbst existiert möglicherweise nicht. nullsollte benutzt werden.

undefinedstellt implizit das Fehlen einer Bedeutung dieses Werts im Kontext Ihrer Anwendung dar. Zum Beispiel, wenn ich ein userObjekt mit einem bestimmten Satz von Eigenschaften manipuliere und versuche, auf die Eigenschaft zuzugreifen pikatchu. Der Wert dieser Eigenschaft sollte festgelegt werden, undefinedda es in meinem Kontext keinen Sinn macht, eine solche Eigenschaft zu haben.

ngryman
quelle
1
Das klingt für mich so wahr. IMO-Funktionen sollten zurückkehren null, während Funktionen mit Nebenwirkungen zurückkehren sollten undefined, wenn Sie wie ein funktionaler Programmierer denken.
Jake
4

undefinedist nicht etwas, dem Sie zuweisen sollten. Möglicherweise möchten Sie etwas anderes als zurückgeben undefined. In Ihrem Fall ist das Ergebnis undefinedbereits vorhanden , auch wenn Sie überhaupt nichts zurückgeben . Also würde ich vorschlagen, stattdessen mit zu gehen null.

Betrachten Sie dieses Beispiel,

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

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

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

Das obige Beispiel ergibt a === b, was ist undefined. Der Unterschied besteht darin, dass Sie 1 Anweisungsausführung speichern.

choz
quelle
@Oriol Ich meine, undefinedmuss nicht zugewiesen werden. Alle deklarierten Variablen ohne Werte sind bereits vorhanden undefined.
Choz
@choz & @Oriol - wie bereits von @chiliNUT erwähnt "Beachten Sie, dass eine Funktion ohne angegebenen Rückgabewert implizit undefiniert zurückgibt." - Dies ist wahr, weil (function(){ /* code */ })()in einer Konsole null zurückgegeben wird.
Jeremy Iglehart
@JeremyIglehart Dieser Code gibt eigentlich nichts zurück. Und sonst gibt es undefinedauf meiner Chrom- und Firefox-Konsole.
Choz
OK, ich habe deinen Standpunkt nicht verstanden. Ja, wenn Sie nichts explizit zurückgeben, wird undefined implizit zurückgegeben. Aber warum ist das wichtig?
Oriol
1
@Oriol, ich denke, was @choz versucht hat zu sagen (wie einige andere auch in dieser Frage erwähnt haben), dass ich nicht zurückkehren muss, undefinedwenn etwas anderes nicht früher zurückkehrt - ich muss es nicht, weil das Standardverhalten der Funktion wenn Sie geben nichts zurück, um undefiniert zurückzukehren - sie sagen nur, dass dies nicht benötigt wird. Weiter ... Mir gefällt, was Sie über integrierte Getter-Funktionen zu sagen hatten, die null zurückgeben. Bitte posten Sie Ihre Antwort in diesem Sinne und ich werde es akzeptieren.
Jeremy Iglehart
2

Hängt davon ab, was Sie mit dem zurückgegebenen Wert tun müssen.

typeof null gibt ein Objekt zurück. Dieses Objekt hat den Wert undefined

typeof undefined gibt undefined zurück

Dan
quelle
Persönlich benutze ich normalerweise null.
Dan
4
"Dieses Objekt hat den Wert undefiniert" Nein, es ist nicht und es ist kein Objekt, es ist Null. typeofGibt nicht unbedingt den wahren Datentyp eines Werts zurück, sondern verfügt über eine Zuordnung, die Datentypen Labels zuordnet und das entsprechende Label zurückgibt.
Felix Kling
Traue nicht typeof, trotz seines Namens sagt es nicht den Typ eines Wertes.
Oriol
2

Hier ist ein Beispiel, wo undefinedmehr Sinn macht als null:

Ich benutze eine Wrapper-Funktion JSON.parse, die ihre Ausnahme in Folgendes konvertiert 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
}

Beachten Sie, dass dies nullin JSON gültig ist, während dies undefinednicht der Fall ist.

masterxilo
quelle
Ich sehe, was Sie dort tun - und ich kann nicht sagen, dass Sie falsch liegen -, denn in gewissem Sinne denke ich, dass Sie dies hier tun könnten und es in Ordnung wäre. Ich habe ein anderes Muster, das ich für diese Operation verwende, das mir besser gefällt, weil ich danach einen "Validierungs" -Schritt durchführe. Ich habe das Gefühl, dass dies die Validierung mit der Rückgabe des Werts vermischt. Folgendes mache ich : let getStringOrJSON = value => { try { value = JSON.parse(value); } catch(e) { return value; } return value; };. Ich bin mir sicher, dass die beiden Renditen unterschiedlich gehandhabt werden könnten und den JS-Golfwettbewerb möglicherweise nicht gewinnen würden. Es klappt.
Jeremy Iglehart
1

Ich denke, es ist sehr umstritten, was zu verwenden ist. Ich bevorzuge Code, der semantisch so genau wie möglich ist, denke ichundefined dies in diesem Fall angemessen.

Ich stelle mir nullZuweisungen als "eine Variable, die auf nichts gesetzt ist" vor. Dies ist im Gegensatz zu der undefinedBedeutung "dieses Ding ist überhaupt nicht da"

Wie bereits in einer früheren Antwort erwähnt, hat die Rückkehr undefinedProbleme, und es liegt ganz bei Ihnen, ob Sie dies stört. Es würde mich nicht stören.

Ryan Laboucane
quelle
2
Aber document.getElementById('iDoNotExist')kehrt zurück null, obwohl die Bedeutung näher an "dieses Ding ist überhaupt nicht da" liegt. Wenn Standardmethoden dies tun, warum nicht OP?
Oriol
@Oriol Ich mag deine Argumentation am liebsten. Bitte senden Sie eine Antwort auf diesen Effekt und ich werde es akzeptieren. (Ich könnte sogar ein paar Änderungen hinzufügen, wenn nötig)
Jeremy Iglehart
Yah @Oriol, deshalb genieße ich Debatten auch auf Q / A-Sites. Es ist wirklich gut, Gegenbeispiele zu bekommen. Und Sie haben eine gute zur Verfügung gestellt.
Ryan Laboucane
1

Ich würde argumentieren, dass in diesem Fall zurückgegeben werden nullsollte.

Wenn Sie die Frage aus theoretischer Informatik betrachten, wird undefiniert verwendet, um die Nichtbeendigung / Nichtberechnbarkeit anzuzeigen (dh den Platzhalter für einen undefinierten Punkt xeiner Teilfunktion, f die häufig geschrieben wird f(x) = ⊥).

getNextCardscheint jedoch in der Lage zu sein, die nächste Karte zu berechnen (falls vorhanden) und auch zu berechnen, wenn es keine nächste Karte gibt. Mit anderen Worten, die Funktion ist total, da sie für jede Eingabe beendet wird.

Davon abgesehen ist ein spezieller Wert erforderlich, der die Beendigung ohne aussagekräftiges Ergebnis signalisiert (dh "Es gibt keine Karte, die ich für diesen Eingang zurückgeben kann"), und dies ist für mich nullnicht der Fall undefined.


ANMERKUNGEN:

Sie können dieses Argument auch in einigen anderen typisierten Sprachen unterstützen, in denen die Beendigung ohne aussagekräftiges Ergebnis mithilfe eines Optionstyps (manchmal auch als nullfähiger Typ bezeichnet ) ausgedrückt wird . Ein Beispiel dafür ist Vielleicht in Haskell .

Andererseits wissen wir natürlich nicht, was undefinedJavaScript eigentlich bedeuten soll. Die Analogie zu undefiniert ist also etwas zart. Da wir immer mit Gesamtfunktionen arbeiten möchten, bedeutet dies außerdem, dass wir niemals undefinedvon einer Funktion zurückkehren. Das scheint etwas streng zu sein, da es die Verwendung undefinedauf Eigenschaften / Variablen beschränken würde, die nicht festgelegt wurden.

Am Ende ist es meine persönliche Präferenz, niemals dorthin zurückzukehren, undefinedwo ich zurückkehren kann, nullund ich würde auch argumentieren, dass dies die bessere Codierungskonvention ist (weil sie unter anderem x !== nullkürzer ist als typeof x !== 'undefined').

FK82
quelle
0

Die erste Antwort ist richtig. Sie haben theoretisch unterschiedliche Bedeutung. Es ist jedoch nicht immer klar, welche Sie abholen sollen.

Ich neige dazu, Null in meiner Entwicklung zu verwenden, obwohl ich denke, dass das völlig subjektiv ist.

Ich benutze das hauptsächlich, weil:

  1. undefinierte Variablen werden in alten Browsern möglicherweise überschrieben, sodass die Rückgabe etwas komplizierter ist. Das gleiche Problem zwingt Sie, typeof var === 'undefined'wenn Sie Funktionsergebnisse erhalten. Verknüpfung

  2. Andere Sprachen verwenden in der Regel häufig Null, viele von ihnen haben nicht einmal undefiniert (z. B. PHP). Das gibt mir eine Art Konsistenz, wenn ich schnell zwischen Sprachen wechsle.

Maciej Paprocki
quelle
-1

Meine persönliche Meinung ist meiner Erfahrung nach, dass Sie nicht undefiniert und null verwenden, wenn Sie Ihren Code nicht zum Absturz bringen möchten. Zumindest würde ich es persönlich vermeiden. Es gibt viele Funktionen in Javascript, die undefiniert zurückgeben, und ok, wir müssen sie verwenden. Aber wenn Sie Ihren Code entwerfen, verwenden Sie ihn nicht. Es ist wichtig, immer "false"mindestens etwas zurückzugeben . Wenn Sie beispielsweise ein Array haben und es zuordnen. Es ist nicht gut zurückzukehren [undefined, undefined.....]oder einfach undefined. Ist besser, wenn Sie den Typ des ursprünglichen Arrays beibehalten. Beispiel:

 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

Das ist die Idee. Ich versuche die ganze Zeit, es zu vermeiden. Weil ein nulloder undefinedIhren Code leicht zum Absturz bringen kann

rubendmatos1985
quelle