1563 Stimmen

Gibt es einen "Null-Koaleszenz"-Operator in JavaScript?

Gibt es einen Null-Koaleszenz-Operator in Javascript?

In C# kann ich zum Beispiel Folgendes tun:

String someString = null;
var whatIWant = someString ?? "Cookies!";

Die beste Annäherung, die ich für Javascript herausfinden kann, ist die Verwendung des Bedingungsoperators:

var someString = null;
var whatIWant = someString ? someString : 'Cookies!';

Was IMHO ziemlich eklig ist. Kann ich es besser machen?

39 Stimmen

Anmerkung aus dem Jahr 2018: x ?? y Die Syntax befindet sich jetzt im Stadium 1 des Vorschlags - Nullische Verschmelzung

4 Stimmen

Es gibt jetzt eine Babel-Plugin die genau diese Syntax enthält.

11 Stimmen

Anmerkung aus dem Jahr 2019: Jetzt ist der Status Stufe 3!

2318voto

Ates Goral Punkte 132294

Update

JavaScript unterstützt jetzt die nullischer Koaleszenzoperator (??) . Er gibt seinen rechten Operanden zurück, wenn sein linker Operand null o undefined und gibt andernfalls den Operanden auf der linken Seite zurück.

Alte Antwort

Bitte überprüfen Sie die Kompatibilität, bevor Sie es verwenden.


Das JavaScript-Äquivalent des C#-Null-Koaleszenz-Operators ( ?? ) ist die Verwendung eines logischen ODER ( || ):

var whatIWant = someString || "Cookies!";

Es gibt Fälle (siehe unten), in denen das Verhalten nicht mit dem von C# übereinstimmt, aber dies ist die allgemeine, knappe Art der Zuweisung von Standard-/Alternativwerten in JavaScript.


Klärung

Unabhängig vom Typ des ersten Operanden ergibt die Umwandlung in einen booleschen Wert false wird für die Zuweisung der zweite Operand verwendet. Achten Sie auf alle unten aufgeführten Fälle:

alert(Boolean(null)); // false
alert(Boolean(undefined)); // false
alert(Boolean(0)); // false
alert(Boolean("")); // false
alert(Boolean("false")); // true -- gotcha! :)

Dies bedeutet:

var whatIWant = null || new ShinyObject(); // is a new shiny object
var whatIWant = undefined || "well defined"; // is "well defined"
var whatIWant = 0 || 42; // is 42
var whatIWant = "" || "a million bucks"; // is "a million bucks"
var whatIWant = "false" || "no way"; // is "false"

56 Stimmen

Zeichenketten wie "false", "undefined", "null", "0", "empty", "deleted" sind alle wahr, da sie nicht-leere Zeichenketten sind.

111 Stimmen

Erwähnenswert ist, dass || den ersten "wahren" Wert oder den letzten "falschen" Wert zurückgibt (wenn keiner als wahr ausgewertet werden kann) und dass && funktioniert umgekehrt: Es wird der letzte richtige Wert oder der erste falsche Wert zurückgegeben.

2 Stimmen

@JustinJohnson hat ein gutes Argument. Diese Antwort vergleicht alle drei: ?? gegen || gegen && .

82voto

Brent Larsen Punkte 1012
function coalesce() {
    var len = arguments.length;
    for (var i=0; i<len; i++) {
        if (arguments[i] !== null && arguments[i] !== undefined) {
            return arguments[i];
        }
    }
    return null;
}

var xyz = {};
xyz.val = coalesce(null, undefined, xyz.val, 5);

// xyz.val now contains 5

Diese Lösung funktioniert wie die SQL-Funktion coalesce, sie akzeptiert eine beliebige Anzahl von Argumenten und gibt null zurück, wenn keines von ihnen einen Wert hat. Sie verhält sich wie der C#-Operator ?? in dem Sinne, dass "", false und 0 als NOT NULL betrachtet werden und daher als tatsächliche Werte zählen. Wenn Sie aus einem .net-Hintergrund kommen, wird dies die natürlichste Lösung sein.

16 Stimmen

Entschuldigung für eine so späte Ergänzung, aber ich wollte nur der Vollständigkeit halber anmerken, dass diese Lösung den Vorbehalt hat, dass sie keine Kurzschlussauswertung hat; wenn Ihre Argumente Funktionsaufrufe sind, dann werden sie alle werden unabhängig davon ausgewertet, ob ihr Wert zurückgegeben wird, was sich vom Verhalten des logischen ODER-Operators unterscheidet und daher erwähnenswert ist.

75voto

vaughan Punkte 6458

Ja, sie wird bald kommen. Siehe Vorschlag hier y Stand der Umsetzung hier .

Das sieht folgendermaßen aus:

x ?? y

Beispiel

const response = {
  settings: {
    nullValue: null,
    height: 400,
    animationDuration: 0,
    headerText: '',
    showSplashScreen: false
  }
};

const undefinedValue = response.settings?.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings?.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings?.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false

47voto

sth Punkte 210180

Si || als Ersatz für C#s ?? in Ihrem Fall nicht ausreicht, weil es leere Zeichenfolgen und Nullen verschluckt, können Sie jederzeit eine eigene Funktion schreiben:

 function $N(value, ifnull) {
    if (value === null || value === undefined)
      return ifnull;
    return value;
 }

 var whatIWant = $N(someString, 'Cookies!');

1 Stimmen

Alert(null || '') meldet immer noch eine leere Zeichenkette, und ich denke, ich mag es eigentlich, dass alert('' || 'blah') eher blah als eine leere Zeichenkette meldet - gut zu wissen, aber! (+1)

2 Stimmen

Ich denke, ich würde es vorziehen, eine Funktion zu definieren, die Folgendes zurückgibt false wenn (strikt) null/undefiniert und true andernfalls - mit einem logischen oder; es könnte lesbarer sein als viele verschachtelte Funktionsaufrufe. z.B. $N(a) || $N(b) || $N(c) || d ist besser lesbar als $N($N($N(a, b), c), d) .

17voto

Kevin Nelson Punkte 7384

Niemand hat hier erwähnt, dass das Potenzial für NaN was für mich ebenfalls ein Nullwert ist. Also dachte ich, ich würde meine Meinung dazu sagen.

Für den angegebenen Code:

var a,
    b = null,
    c = parseInt('Not a number'),
    d = 0,
    e = '',
    f = 1
;

Wenn Sie die || Operator, erhält man den ersten nicht-falschen Wert:

var result = a || b || c || d || e || f; // result === 1

Wenn Sie das neue ?? (Null-Koaleszenz-Operator), erhalten Sie c , die den Wert hat: NaN

vas result = a ?? b ?? c ?? d ?? e ?? f; // result === NaN

Weder erscheinen mir richtig. In meiner eigenen kleinen Welt der Coalesce-Logik, die sich von Ihrer Welt unterscheiden mag, betrachte ich undefiniert, null und NaN als "null-ish". Ich würde also erwarten, dass ich zurückkomme d (Null) aus der Koaleszenzmethode.

Wenn das Gehirn von jemandem so funktioniert wie meines, und Sie ausschließen wollen NaN dann wird dieser Brauch coalesce Methode (im Gegensatz zu das hier gepostete ) wird dies erreichen:

function coalesce() {
    var i, undefined, arg;

    for( i=0; i < arguments.length; i++ ) {
        arg = arguments[i];
        if( arg !== null && arg !== undefined
            && (typeof arg !== 'number' || arg.toString() !== 'NaN') ) {
            return arg;
        }
    }
    return null;
}

Für diejenigen, die den Code so kurz wie möglich halten wollen und denen ein wenig Unklarheit nichts ausmacht, können auch diesen Code verwenden, wie von @impinball vorgeschlagen. Dies macht sich die Tatsache zunutze, dass NaN niemals gleich NaN ist. Mehr dazu können Sie hier nachlesen: Warum ist NaN nicht gleich NaN?

function coalesce() {
    var i, arg;

    for( i=0; i < arguments.length; i++ ) {
        arg = arguments[i];
        if( arg != null && arg === arg ) { //arg === arg is false for NaN
            return arg;
        }
    }
    return null;
}

0 Stimmen

Bewährte Praktiken - Argumente als Array-ähnlich behandeln, Vorteile von NaN !== NaN ( typeof + num.toString() === 'NaN' ist redundant), speichern Sie das aktuelle Argument in der Variable statt arguments[i] .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X