Pregunta

¿Hay un operador de fusión 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?

¿Fue útil?

Solución

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

var whatIWant = someString || "Cookies!";

Hay casos (aclarados a continuación) en los 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 convertirlo a un Booleano da como resultado false , la asignación utilizará 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"

Otros consejos

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 un valor nulo si ninguno de ellos tiene un valor. Se comporta como el C # ?? operador en el sentido de que " ;, falso, y 0 se consideran NO NULL y, por lo tanto, cuentan como valores reales. Si vienes de un fondo .net, esta será la solución de sensación más natural.

Si || como reemplazo de ?? de C # no es lo suficientemente bueno en su caso, ya que absorbe cadenas y ceros vacíos, siempre puede escribir el suyo propio función:

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

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

Sí, llegará pronto. Consulte propuesta aquí y estado de implementació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

Nadie ha mencionado aquí el potencial de 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 usara el operador || , obtendría 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 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 lógica de fusión, que puede diferir de su mundo, considero que indefinido, nulo y NaN son todos "nulos". Por lo tanto, esperaría recuperar d (cero) del método de fusión.

Si el cerebro de alguien funciona como el mío, y desea 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 pueden 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;
}

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

tenga cuidado con la definición específica de JavaScript de nulo. 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. así:

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 Objeto. 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. así:

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

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

observe que si utiliza el operador de comparación de conversión de tipo (==), JavaScript actuará igualmente para ambos valores vacíos. para distinguirlos, use siempre el operador de comparación de tipo estricto (===).

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 nulo; sin embargo, es importante tener en cuenta la diferencia en == versus === en JavaScript especialmente cuando se trata de problemas para verificar undefined y / o null .

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

¡JS está obteniendo un operador de fusión nulo ahora! Actualmente en la Etapa 3 pasando a la Etapa 4, ¡sí! https://github.com/tc39/proposal-nullish-coalescing

ejemplo en la propuesta:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top