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


Gibt es in Javascript einen Koaleszenzoperator?

Zum Beispiel kann ich in C # Folgendes tun:

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

Die beste Näherung, die ich für Javascript herausfinden kann, ist der Bedingungsoperator:

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

Was ist sick icky IMHO. Kann ich es besser machen?


968
2018-01-24 18:18


Ursprung


Antworten:


Das JavaScript-Äquivalent des Koaleszenzoperators C # null (??) verwendet ein logisches ODER (||):

var whatIWant = someString || "Cookies!";

Es gibt Fälle (die im Folgenden erläutert werden), dass 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, wenn es in einen Booleschen Wert umgewandelt wird false, verwendet die Zuweisung den zweiten Operanden. Hüten Sie sich vor allen folgenden Fällen:

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

Das heisst:

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"

1565
2018-01-24 18:25



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-Coalesce-Funktion, sie akzeptiert eine beliebige Anzahl von Argumenten und gibt null zurück, wenn keiner von ihnen einen Wert hat. Es verhält sich wie die C # ?? Operator in dem Sinne, dass "", false und 0 als NOT NULL betrachtet werden und daher als tatsächliche Werte zählen. Wenn Sie von einem .net Hintergrund kommen, wird dies die natürlichste Gefühlslösung sein.


56
2018-03-08 05:24



Ob || als Ersatz für C # ?? ist in deinem Fall nicht gut genug, denn es schluckt leere Strings und Nullen, du kannst immer deine eigene Funktion schreiben:

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

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

38
2018-01-24 18:45



Niemand hat hier das Potential dafür erwähnt NaN, was - für mich - auch ein null-ish-Wert ist. Also dachte ich, ich würde meine zwei Cent hinzufügen.

Für den angegebenen Code:

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

Wenn du das benutzen würdest || Operator erhält man den ersten Nicht-Falsch-Wert:

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

Wenn Sie die typische Koaleszenzmethode verwenden, wie hier gepostet, Sie erhalten c, die den Wert hat: NaN

var result = coalesce(a,b,c,d,e,f); // result.toString() === 'NaN'

Weder von diesen scheinen mir richtig. In meiner eigenen kleinen Welt der Koaleszenzlogik, die sich von Ihrer Welt unterscheiden kann, betrachte ich undefined, null und NaN als alles "null-ish". Also würde ich erwarten, zurück zu kommen d (Null) von der Koaleszenzmethode.

Wenn irgendjemandes Gehirn so funktioniert wie ich, und du es ausschließen willst NaN, dann wird diese Methode das 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 möchten, und einen kleinen Mangel an Klarheit haben, können Sie dies auch wie von @impinball vorgeschlagen verwenden. Dies nutzt die Tatsache aus, 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;
}

10
2018-05-26 21:07



Derzeit gibt es keine Unterstützung, aber der JS-Standardisierungsprozess arbeitet daran: https://github.com/tc39/proposal-optional-chaining


6
2017-07-16 21:17



Ja, es kommt bald. Sehen Vorschlag hier und Implementierungsstatus hier.

Es sieht aus wie das:

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

5
2018-05-07 09:32



Achten Sie auf die JavaScript-spezifische Definition von null. Es gibt zwei Definitionen für "kein Wert" in JavaScript. 1. Null: Wenn eine Variable null ist, bedeutet das, dass sie keine Daten enthält, aber die Variable ist bereits im Code definiert. so was:

var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts

In diesem Fall ist der Typ Ihrer Variablen eigentlich Objekt. Probier es aus.

window.alert(typeof myEmptyValue); // prints Object
  1. Nicht definiert: Wenn eine Variable zuvor im Code nicht wie erwartet definiert wurde, enthält sie keinen Wert. so was:

    if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
    // alerts
    

In diesem Fall ist der Typ Ihrer Variablen "undefiniert".

Beachten Sie, dass bei Verwendung des typkonvertierenden Vergleichsoperators (==) JavaScript für beide Leerwerte gleichermaßen gilt. Um zwischen ihnen zu unterscheiden, verwenden Sie immer den Typ-strikte Vergleichsoperator (===).


4
2018-01-24 18:35



Nachdem Sie Ihre Klarstellung gelesen haben, können Sie in der Antwort von @Ates Goral erfahren, wie Sie denselben Vorgang in C # in JavaScript ausführen.

@ Gumbo's Antwort bietet die beste Möglichkeit, nach Null zu suchen; Es ist jedoch wichtig, den Unterschied zu beachten == gegen === in JavaScript insbesondere wenn es um Fragen der Kontrolle geht undefined und / oder null.

Es gibt einen wirklich guten Artikel über den Unterschied in zwei Begriffen Hier. Im Grunde verstehen Sie, dass wenn Sie verwenden == Anstatt von ===, JavaScript wird versuchen, die Werte, die Sie vergleichen, zusammenzuführen und das Ergebnis des Vergleichs zurückzugeben nach diese Koaleszenz.


3
2018-01-24 18:23