Pergunta

Existe um nulo coalescentes operador em JavaScript?

Por exemplo, em C #, eu posso fazer isso:

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

A melhor aproximação que eu possa descobrir por Javascript está usando o operador condicional:

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

O que é sorta IMHO icky. Eu posso fazer melhor?

Foi útil?

Solução

O equivalente do JavaScript C # nulo coalescência operador (??) está a utilizar um OR lógico (||):

var whatIWant = someString || "Cookies!";

Existem casos (esclarecidas abaixo) que o comportamento não irá corresponder ao C #, mas este é o geral, concisa maneira de atribuir valores padrão / alternativas em JavaScript.


Clarificação

Independentemente do tipo do primeiro operando, se lançando-a um booleano resulta em 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! :)

Este meios:

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"

Outras dicas

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 solução funciona como a função SQL coalesce, ele aceita qualquer número de argumentos e retorna null se nenhum deles tem um valor. Ele se comporta como o C # ?? operador no sentido de que "" falso e 0 são considerados NOT NULL e, portanto, contar como valores reais. Se você vem de um fundo .net, esta será a solução mais natural sentimento.

Se || como um substituto de ?? C # 's não é bom o suficiente no seu caso, porque engole cadeias vazias e zeros, você sempre pode escrever sua própria função:

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

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

Sim, ele está chegando. Ver proposta aqui e estado de implementação aqui .

Parece que este:

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

Ninguém mencionou aqui o potencial para NaN, que - para mim - também é um valor nulo-ish. Então, eu pensei que eu gostaria de acrescentar meus dois centavos.

Para o código dado:

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

Se você fosse usar o operador ||, você recebe o primeiro valor diferente de false:

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

Se você usar o método coalesce típico, como postamos 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. Em meu próprio mundo pequeno da lógica coalesce, que pode diferir do seu mundo, considero indefinida, null, e NaN como todo ser "nulo-ish". Então, eu esperaria para obter d volta (zero) a partir do método coalesce.

Se o cérebro de quem trabalha como o meu, e você deseja excluir NaN, em seguida, esse método irá conseguir 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 tão curto quanto possível, e não se importa um pouco de falta de clareza, você também pode usar isso como sugerido por @impinball. Este aproveita o fato de que NaN nunca é 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 nenhum apoio, mas o processo JS-padronização está trabalhando nisso: https: // github .com / TC39 / proposta opcional-encadeamento

cuidado com a definição específica JavaScript de null. existem duas definições para "nenhum valor" em javascript. 1. nulo: quando uma variável é nula, isso significa que não contém dados na mesma, mas a variável já está definido no código. assim:

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

Nesse caso, o tipo de variável é realmente objeto. testá-lo.

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

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

Se tal caso, o tipo de variável é 'indefinido'.

Observe que se você usar o operador de comparação de conversão tipo (==), JavaScript irá funcionar igualmente para ambos os valores vazios. para distinguir entre eles, utilizar sempre o operador de comparação tipo-estrita (===).

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

@ resposta de Gumbo fornece a melhor maneira de verificar se há null; No entanto, é importante notar a diferença no == contra === em JavaScript especialmente quando se trata de questões de verificação de undefined e / ou null.

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

JS está ficando um nulo coalescentes operador agora! Actualmente no Stage-3 se movendo para Stage-4, yay! https://github.com/tc39/proposal-nullish-coalescing

exemplo na proposta:

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top