¿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 averiguar para Javascript es usando el operador condicional:

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

Que es algo asqueroso en mi humilde opinión. ¿Puedo hacerlo mejor?

Author: user2864740, 2009-01-24

8 answers

El equivalente de JavaScript del operador coalescente null de C #(??) está usando un (||):

var whatIWant = someString || "Cookies!";

Hay casos (aclarados a continuación) 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 el lanzamiento a un booleano resulta en false, la asignación utilizará el segundo operando. Cuidado con todos los casos abajo:

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"
 1627
Author: Ates Goral,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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

Esta solución funciona como la función SQL coalesce, acepta cualquier número de argumentos y devuelve null si ninguno de ellos tiene un valor. ¿Se comporta como el C# ?? operador en el sentido de que"", false y 0 se consideran NO NULOS y por lo tanto cuentan como valores reales. Si usted viene de un fondo.net, esta será la solución de sensación más natural.

 59
Author: Brent Larsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-19 18:42:35

Si || como reemplazo de C#'s ?? no es lo suficientemente bueno en su caso, porque se 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
Author: sth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-09 16:42:53

Nadie ha mencionado aquí el potencial para NaN, que me para mí also es también un valor null-ish. Así que pensé en añadir mis dos centavos.

Para el código dado:

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

Si utilizas el operador ||, obtienes el primer valor no falso:

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

Si usa el método típico de coalescencia, como se publica aquí, obtendrá c, que tiene el valor: NaN

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

Ninguno de estos me parece correcto. En mi pequeño mundo de la lógica de fusión, que puede diferir de su mundo, considero indefinido, nulo y NaN como todos siendo "null-ish". Por lo tanto, esperaría volver d (cero) del método coalesce.

Si el cerebro de alguien funciona como el mío, y quieres excluir 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. Puedes leer más sobre esto 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
Author: Kevin Nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:54

Sí, está llegando pronto. Véase la propuesta aquíy el estado de aplicación aquí.

Se ve así:

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
 9
Author: vaughan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-07 09:32:28

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

 6
Author: Elmar Jansen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-16 21:17:38

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

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

En tal caso, el tipo de su variable es realmente Objeto. pruébalo.

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

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

Si tal caso, el tipo de su variable es 'undefined'.

Observe que si usa el operador de comparación de conversión de tipos (==), JavaScript actuará igualmente para ambos valores vacíos. para distinguir entre ellos, utilice siempre el operador de comparación type-strict (===).

 4
Author: farzad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-08 14:53:16

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 problemas de verificar undefined y/o null.

Hay un muy buen artículo sobre la diferencia en dos términos aquí. Básicamente, entender que si usted use == en lugar de ===, JavaScript intentará fusionar los valores que está comparando y devolver lo que el resultado de la comparación después de esta coalescencia.

 3
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-24 18:29:21