Existe um operador de “coalescência nula” em JavaScript?

Existe um operador de coalescência nulo em JavaScript?

Por exemplo, em c #, posso fazer isso:

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

A melhor aproximação que eu posso descobrir para o Javascript é usando o operador condicional:

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

Que é uma espécie de IMHO nojento. Posso fazer melhor?

   

O equivalente JavaScript do operador de coalescência nula C # ( ?? ) está usando um OR lógico ( || ):

 var whatIWant = someString || "Cookies!"; 

Há casos (esclarecidos abaixo) de que o comportamento não corresponderá ao de C #, mas essa é a maneira geral e concisa de atribuir valores padrão / alternativos em JavaScript.


Esclarecimento

Independentemente do tipo do primeiro operando, se a conversão para um resultado booleano for false , a atribuição usará o segundo operando. Cuidado com todos os casos abaixo:

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

Isso 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" 
 function coalesce() { var len = arguments.length; for (var i=0; i 

essa solução funciona como a function de união de SQL, aceita qualquer número de argumentos e retorna null se nenhum deles tiver um valor. Ele se comporta como o C #? operador no sentido de que "", falso e 0 são considerados NOT NULL e, portanto, contam como valores reais. Se você vem de um fundo .net, esta será a solução de sentimento mais natural.

Se || como um substituto do C # ‘s ?? não é bom o suficiente no seu caso, porque ele engole strings e zeros vazios, você sempre pode escrever sua própria function:

  function $N(value, ifnull) { if (value === null || value === undefined) return ifnull; return value; } var whatIWant = $N(someString, 'Cookies!'); 

Ninguém mencionou aqui o potencial do NaN , que – para mim – também é um valor nulo. Então, pensei em acrescentar meus dois centavos.

Para o código fornecido:

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

Se você fosse usar o || operador, você obtém o primeiro valor não falso:

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

Se você usar o método típico de coalesce, como postado aqui , você receberá c , que tem o valor: NaN

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

Nenhum destes parece certo para mim. No meu pequeno mundo de lógica de coalescência, que pode diferir do seu mundo, considero indefinido, nulo e NaN como sendo tudo “nulo-ish”. Então, eu esperaria voltar d (zero) do método de coalescência.

Se o cérebro de alguém funciona como o meu, e você quer excluir o NaN , esse método fará isso:

 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 aqueles que querem o código o mais curto possível, e não se preocupam com a falta de clareza, você também pode usar isso como sugerido por @impinball. Isso aproveita o fato de NaN nunca ser igual a NaN. Você pode ler mais sobre isso aqui: Por que NaN não é 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; } 

Atualmente não há suporte, mas o processo de padronização do JS está trabalhando nele: https://github.com/tc39/proposal-optional-chaining

Sim, está chegando em breve. Veja a proposta aqui e o status da implementação aqui .

Se parece com isso:

 x ?? y 

Exemplo

 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 

Cuidado com a definição específica de JavaScript de null. Existem duas definições para “sem valor” no javascript. 1. Nulo: quando uma variável é nula, isso significa que ela não contém dados, mas a variável já está definida no código. como isso:

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

Nesse caso, o tipo de sua variável é, na verdade, Object. teste-o.

 window.alert(typeof myEmptyValue); // prints Object 
  1. Indefinido: quando uma variável não foi definida antes no código e como esperado, ela não contém nenhum valor. como isso:

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

se tal caso, o tipo de sua variável é ‘indefinido’.

Observe que, se você usar o operador de comparação de conversão de tipos (==), o JavaScript funcionará de maneira igual para esses dois valores vazios. para distinguir entre eles, use sempre o operador de comparação type-strict (===).

Depois de ler o seu esclarecimento, a resposta do @Ates Goral fornece como realizar a mesma operação que você está fazendo em C # em JavaScript.

A resposta do @Gumbo fornece a melhor maneira de verificar se há nulo; no entanto, é importante observar a diferença em == versus === no JavaScript, especialmente quando se trata de problemas de verificação para undefined e / ou null .

Há um artigo muito bom sobre a diferença em dois termos aqui . Basicamente, entenda que se você usar == vez de === , o JavaScript tentará coalescer os valores que você está comparando e retornará o resultado da comparação após essa coalescência.