Y a-t-il un opérateur "null coalescing" dans JavaScript?

y a-t-il un opérateur de coalescence null en Javascript?

par exemple, dans C#, je peux faire ceci:

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

la meilleure approximation que je puisse trouver pour Javascript est l'utilisation de l'opérateur conditionnel:

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

qui est en quelque sorte IMHO icky. Puis-je faire de mieux?

1006
demandé sur user2864740 2009-01-24 21:18:02

8 réponses

l'équivalent JavaScript de l'opérateur de coalescence c # null ( ?? ) utilise un ou logique ( || ):

var whatIWant = someString || "Cookies!";

il y a des cas (clarifiés ci-dessous) où le comportement ne correspondra pas à celui de C#, mais c'est la façon générale et lente d'attribuer des valeurs par défaut/alternatives en JavaScript.


Clarification

quel que soit le type du premier opérande, s'il est moulé à un booléen donne false , la tâche utilisera le second opérande. Méfiez-vous de tous les cas ci-dessous:

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

cela signifie:

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"
1627
répondu Ates Goral 2009-01-24 19:10:23
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

cette solution fonctionne comme la fonction SQL coalesce, elle accepte n'importe quel nombre d'arguments, et renvoie null si aucun d'eux n'a de valeur. Il se comporte comme le C# ?? opérateur dans le sens que "", faux, et 0 ne sont pas considérés comme nuls et donc comptent comme des valeurs réelles. Si vous venez d'un arrière-plan.net, ce sera la solution la plus naturelle.

59
répondu Brent Larsen 2015-11-19 18:42:35

si || comme un remplacement de C#'s ?? n'est pas assez bon dans votre cas, parce qu'il avale des chaînes vides et des zéros, vous pouvez toujours écrire votre propre fonction:

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

 var whatIWant = $N(someString, 'Cookies!');
38
répondu sth 2017-11-09 16:42:53

personne n'a mentionné ici le potentiel pour NaN , qui--pour moi--est aussi une valeur null-ish. Alors, j'ai pensé ajouter mes deux cents.

pour le code donné:

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

si vous utilisez l'opérateur || , vous obtenez la première valeur non-false:

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

si vous utilisez la méthode coalesce typique, comme posté ici , vous obtiendrez c , qui a le valeur: NaN

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

ni l'un ni l'autre ne me semblent justes. Dans mon propre petit monde de logique coalescente, qui peut différer de votre monde, je considère indéfini, null, et NaN comme tous étant "null-ish". Donc, je m'attendrais à revenir d (zéro) de la méthode coalesce.

si le cerveau de quelqu'un fonctionne comme le mien, et vous voulez exclure NaN , alors cette méthode accomplira que:

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

pour ceux qui veulent que le code soit aussi court que possible, et ne vous gênez pas d'un petit manque de clarté, vous pouvez également utiliser ceci comme suggéré par @impinball. Cela profite du fait que NaN n'est jamais égale à NaN. Vous pouvez lire plus sur ce ici: pourquoi NaN n'est pas égal à 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
répondu Kevin Nelson 2017-05-23 12:10:54

Oui, il arrive bientôt. Voir proposition et état de mise en œuvre ici .

il ressemble à ceci:

x ?? y

exemple

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
9
répondu vaughan 2018-05-07 09:32:28

actuellement pas de support, mais le processus de standardisation JS travaille dessus: https://github.com/tc39/proposal-optional-chaining

6
répondu Elmar Jansen 2017-07-16 21:17:38

méfiez-vous du JavaScript définition précise de la valeur null. il y a deux définitions pour "aucune valeur" dans javascript. 1. Null: quand une variable est nulle, cela signifie qu'il ne contient pas de données, mais la variable est déjà défini dans le code. comme ceci:

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

dans ce cas, le type de votre variable est en fait objet. tester.

window.alert(typeof myEmptyValue); // prints Object
  1. Non défini: lorsqu'une variable n'a pas été définie auparavant dans la code, et comme prévu, il ne contient aucune valeur. comme ceci:

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

si tel est le cas, le type de votre variable est "non défini".

notez que si vous utilisez L'opérateur de comparaison de type (==), JavaScript agira également pour ces deux valeurs vides. pour les distinguer, toujours utiliser l'opérateur de comparaison stricte (===).

4
répondu farzad 2014-04-08 14:53:16

après avoir lu votre clarification, la réponse de @Ates Goral explique comment effectuer la même opération que vous faites en C# en JavaScript.

la réponse de @Gumbo fournit la meilleure façon de vérifier Pour null; cependant, il est important de noter la différence dans == versus === en JavaScript surtout quand il s'agit de vérifier pour undefined et/ou null .

il y a un très bon article sur la différence en deux termes ici . Fondamentalement, comprendre que si vous utilisez == au lieu de === , JavaScript va essayer de coalesce les valeurs que vous comparez et de retourner ce que le résultat de la comparaison après cette coalescence.

3
répondu Tom 2009-01-24 18:29:21