¿Existe una & # 8220; fusión nula & # 8221; operador en JavaScript?
-
20-08-2019 - |
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?
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
-
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