Pregunta ¿Hay un operador de "coalescencia nula" en JavaScript?


¿Hay un operador coalescente nulo en Javascript?

Por ejemplo, en C #, puedo hacer esto:

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

La mejor aproximación que puedo encontrar para Javascript es usar el operador condicional:

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

Lo cual es bastante asqueroso en mi humilde opinión. ¿Puedo hacerlo mejor?


968
2018-01-24 18:18


origen


Respuestas:


El equivalente de JavaScript del operador coalescente nulo de C # (??) está utilizando un OR lógico (||)

var whatIWant = someString || "Cookies!";

Hay casos (aclarados a continuación) de que el comportamiento no coincidirá con el de C #, pero esta es la forma general y concisa de asignar valores predeterminados / alternativos en JavaScript.


Aclaración

Independientemente del tipo del primer operando, si lo convierte en un booleano da como resultado false, la asignación usará el segundo operando. Tenga cuidado con todos los casos a continuación:

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

Esto significa:

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

esta solución funciona como la función de fusión de SQL, acepta cualquier número de argumentos y devuelve nulo si ninguno de ellos tiene un valor. ¿Se comporta como el C #? operador en el sentido de que "", falso y 0 se consideran NOT NULL y, por lo tanto, cuentan como valores reales. Si proviene de un fondo .net, esta será la solución de sensación más natural.


56
2018-03-08 05:24



Si || como un reemplazo de C # 's ?? no es lo suficientemente bueno en su caso, porque traga cadenas vacías y ceros, siempre puede escribir su propia función:

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

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

38
2018-01-24 18:45



Nadie ha mencionado aquí el potencial para NaN, que para mí también es un valor nulo. Entonces, pensé que agregaría mis dos centavos.

Para el código dado:

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

Si fueras a usar el || operador, obtienes el primer valor no falso:

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

Si usa el método de fusión típico, como se publicó aquí, conseguirás c, que tiene el valor: NaN

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

Ninguno de estos me parecen correctos En mi pequeño mundo de lógica coalescente, que puede diferir de tu mundo, considero indefinido, nulo y NaN como todos "nulos". Entonces, esperaría volver d (cero) del método de coalescencia.

Si el cerebro de alguien funciona como el mío, y quieres excluirlo NaN, entonces este método logrará eso:

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

Para aquellos que quieren el código lo más corto posible, y no les importa un poco la falta de claridad, también puede usar esto como lo sugiere @impinball. Esto aprovecha el hecho de que NaN nunca es igual a NaN. Puede leer más sobre eso aquí: ¿Por qué NaN no es igual a 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



Actualmente no hay soporte, pero el proceso de estandarización JS está trabajando en ello: https://github.com/tc39/proposal-optional-chaining


6
2017-07-16 21:17



Sí, llegará pronto Ver propuesta aquí y estado de implementación aquí.

Se parece a esto:

x ?? y

Ejemplo

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



tenga cuidado con la definición específica de JavaScript de null. hay dos definiciones para "sin valor" en javascript. 1. Nulo: cuando una variable es nula, significa que no contiene datos, pero la variable ya está definida en el código. Me gusta esto:

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

en tal caso, el tipo de su variable es en realidad Object. Pruébalo.

window.alert(typeof myEmptyValue); // prints Object
  1. Indefinido: cuando una variable no se ha definido antes en el código, y como se esperaba, no contiene ningún valor. Me gusta esto:

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

si tal caso, el tipo de su variable es 'indefinido'.

observe que si usa el operador de comparación de conversión de tipos (==), JavaScript actuará de manera equitativa para estos dos valores vacíos. para distinguirlos, utilice siempre el operador de comparación de tipo estricto (===).


4
2018-01-24 18:35



Después de leer su aclaración, la respuesta de @Ates Goral proporciona cómo realizar la misma operación que está haciendo en C # en JavaScript.

La respuesta de @Gumbo proporciona la mejor manera de verificar null; Sin embargo, es importante notar la diferencia en == versus === en JavaScript especialmente cuando se trata de cuestiones de verificación de undefined y / o null.

Hay un artículo realmente bueno sobre la diferencia en dos términos aquí. Básicamente, entienda que si usa == en lugar de ===, JavaScript intentará combinar los valores que está comparando y devolverá el resultado de la comparación después esta fusión.


3
2018-01-24 18:23