Existe uma função padrão para verificar variáveis ​​nulas, indefinidas ou em branco no JavaScript?

2260

Existe uma função JavaScript universal que verifica se uma variável tem um valor e garante que não é undefinedou não null? Eu tenho esse código, mas não tenho certeza se ele cobre todos os casos:

function isEmpty(val){
    return (val === undefined || val == null || val.length <= 0) ? true : false;
}
Alex
fonte
5
possível duplicata de Como você verifica uma cadeia vazia em JavaScript?
Dour High Arch
78
Protip, nunca faça (truthy statement) ? true : false;. Apenas faça (truthy statement);.
David Baucum 02/08/19
5
@GeorgeJempty não é um idiota, já que a outra resposta pergunta sobre strings em particular, enquanto essa pergunta sobre variáveis .
Madbreaks
2
Qualquer resposta correta para essa pergunta depende inteiramente de como você define "em branco".
Madbreaks
3
@ Jay Não dói nada, tanto quanto a execução do seu código. É apenas muito detalhado. Você não diria: "Você está com fome, é verdade?" Você apenas "está com fome" Então, no código, basta dizer em if (hungry) …vez de if (hungry === true) …. Como todas as coisas de codificação dessa maneira, é apenas uma questão de gosto. Mais específico ao exemplo fornecido pelo OP, ele está dizendo ainda mais detalhadamente: "Se é verdade, então é verdade, se não for então falsa" Mas se for verdade, então já é verdade. E, se for falso, já é falso. Isso é semelhante a dizer "Se você está com fome, então está e, se não, não está".
David Baucum

Respostas:

4379

Você pode apenas verificar se a variável tem um truthyvalor ou não. Que significa

if( value ) {
}

avaliará truese nãovalue é :

  • nulo
  • Indefinido
  • NaN
  • sequência vazia ("")
  • 0 0
  • falso

A lista acima representa todos os falsyvalores possíveis em ECMA- / Javascript. Encontre-o na especificação na ToBooleanseção.

Além disso, se você não souber se existe uma variável (ou seja, se foi declarada ), verifique com o typeofoperador. Por exemplo

if( typeof foo !== 'undefined' ) {
    // foo could get resolved and it's defined
}

Se você pode ter certeza de que uma variável é declarada pelo menos, verifique diretamente se ela possui um truthyvalor como o mostrado acima.

Leia mais: http://typeofnan.blogspot.com/2011/01/typeof-is-fast.html

jAndy
fonte
110
E se o valor for um falso booleano pretendido. Às vezes, você deseja atribuir um valor padrão se não houver valor, o que não funcionará se o falso booleano for passado.
TruMan1
100
@ TruMan1: nesse caso (em que sua lógica determina a validação), você deve seguir o exemplo if( value || value === false ). O mesmo vale para todos os valores falsos , precisamos validá-los explicitamente.
Jandy
28
Exceto se o valor for uma matriz. A interpretação de truthypoderia ser enganosa. Nesse caso, deveríamos procurar value.length != 0uma matriz não vazia.
usuário
12
Só quero acrescentar que, se você sentir a ifconstrução é sintaticamente muito pesado, você poderia usar o operador ternário, assim: var result = undefined ? "truthy" : "falsy". Ou se você quer apenas para coagir a um valor booleano, use o !!operador, por exemplo !!1 // true, !!null // false.
KFL
7
Observe também que isso não verificará as strings que contêm apenas caracteres de espaço em branco.
Christophe Roussy
222

O método detalhado para verificar se o valor é indefinido ou nulo é:

return value === undefined || value === null;

Você também pode usar o ==operador, mas espera-se que conheça todas as regras :

return value == null; // also returns true if value is undefined
Salman A
fonte
33
Verificando por apenas nullou undefinedpode ser feito da seguinte forma: if (value == null). Cuidado com o ==operador que coagir. Se você marcar assim if (value === null || value === undefined), você esqueceu / não sabe como o Javascript coage. webreflection.blogspot.nl/2010/10/…
Christiaan Westerbeek
32
@ChristiaanWesterbeek: seu ponto de vista que arg == nullproduz os mesmos resultados que arg === undefined || arg === null. No entanto, considero o último exemplo mais legível.
Salman Uma
10
arg == nullé bastante comum na minha experiência.
Bryan Downing #
8
return value === (void 0)é mais seguro do que o teste contra o undefinedqual pode muito bem ser uma variável legítima em escopo, infelizmente.
x0n 19/01/16
4
@Sharky Há uma diferença entre uma variável que é indefinido e uma variável não declarada: lucybain.com/blog/2014/null-undefined-undeclared
Christiaan Westerbeek
80
function isEmpty(value){
  return (value == null || value.length === 0);
}

Isso retornará verdadeiro para

undefined  // Because undefined == null

null

[]

""

e zero funções de argumento, já que uma função lengthé o número de parâmetros declarados necessários.

Para não permitir a última categoria, convém verificar se há strings em branco

function isEmpty(value){
  return (value == null || value === '');
}
Mike Samuel
fonte
7
undefined == nullmasundefined !== null
Ian Boyd
2
@IanBoyd é porque você está comparando == a ===. isso significa que undefined == null (true) undefined! = null (false) undefined === null (false) undefined! == null (true) seria melhor fornecer um pouco mais de informações para ajudar e empurrar as pessoas na direção certa. moz doc sobre a diferença developer.mozilla.org/pt-BR/docs/Web/JavaScript/…
Corey Young
43

Esta é a verificação mais segura e eu não a vi postada aqui exatamente assim:

if (typeof value !== 'undefined' && value) {
    //deal with value'
};

Abrangerá casos em que o valor nunca foi definido e também qualquer um destes:

  • nulo
  • undefined (o valor de undefined não é o mesmo que um parâmetro que nunca foi definido)
  • 0 0
  • "" (sequência vazia)
  • falso
  • NaN

Editado: alterado para igualdade estrita (! ==) porque já é a norma;)

guya
fonte
10
Não reduzi o voto, mas no que diz respeito à comparação estrita de igualdade, a regra geral é que, a menos que você precise de conversão implícita de tipo, a comparação estrita deve ser usada.
precisa saber é o seguinte
2
Thanx pelo seu comentário Steve. Essa regra geral está bem. Eu só espero que as pessoas entendam porque eles usam um ou outro. De todas as maneiras que você olhar, terá prazer em pregar a você sobre "sempre use sempre rigoroso" - como se fosse a coisa mais importante em Javascript. Já vi muitos casos como if (val! == null) que obviamente levam a um resultado indesejado. Não há problema em dizer que, quando estiver em dúvida - use rigoroso, mas é melhor não estar em dúvida.
Guya
6
Penso que o ponto aqui é que esperamos que o typeofoperador retorne uma string, portanto, usar a estrita verificação de igualdade é tecnicamente mais preciso, mais específico e mais rápido. Então, realmente, não há razão para usar a comparação solta, e não o contrário. Também val !== nullé perfeitamente válido em muitos casos - eu faço isso o tempo todo. Concordo com o seu argumento de não conformidade, mas acho que este é um mau exemplo para fazê-lo. Não tentando trollar você.
Bryan Downing
Obrigado pelo seu comentário Bryan, Você usa val! == null porque você sabe o que está fazendo. Um iniciante desejará ter um retorno quando val for falso. Mas, val nunca será nulo, será indefinido. Se ele não escutasse esse conselho de "sempre use rigorosamente", ele terá menos bugs. Eu já vi isso acontecer no código de produção. typeof sempre retorna uma string e o diferencial de velocidade será redundante. Portanto, o único argumento para o uso de strict no caso acima é consistência. Eu disse: "Não há necessidade de igualdade estrita". Isso não significa que você não pode, se quiser ou se tornar seu código mais consistente.
Guya
28

Você pode achar útil a seguinte função:

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}

Ou no ES7 (comente se houver mais melhorias)

function typeOf(obj) {
  const { toString } = Object.prototype;
  const stringified = obj::toString();
  const type = stringified.split(' ')[1].slice(0, -1);

  return type.toLowerCase();
}

Resultados:

typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map

"Observe que o operador de ligação (: :) não faz parte do ES2016 (ES7) nem de nenhuma edição posterior do padrão ECMAScript. Atualmente, é uma proposta do estágio 0 (strawman) para ser introduzida no idioma." Simon Kjellberg. o autor deseja acrescentar seu apoio a esta bela proposta de receber ascensão real.

Vix
fonte
+1 é útil conhecer o objeto do tipo 'regexp' , 'array' e 'function'
Yash
@Vix, por que a versão ES7 é melhor?
precisa saber é o seguinte
Não é, estava experimentando maneiras mais legíveis de expressar a mesma funcionalidade usando: atribuição de desestruturação, operador de ligação.
Vix
2
Observe que o operador de ligação ( ::) não faz parte do ES2016 (ES7) nem de nenhuma edição posterior do padrão ECMAScript. Atualmente, é uma proposta do estágio 0 (strawman) para ser introduzida no idioma.
Simon Kjellberg
25

A primeira resposta com a melhor classificação está errada. Se o valor for indefinido, lançará uma exceção nos navegadores modernos. Você tem que usar:

if (typeof(value) !== "undefined" && value)

ou

if (typeof value  !== "undefined" && value)
krupar
fonte
3
eee ... Eu acho que isso está errado como se (valor) fosse suficiente (exceto objetos / matrizes vazios). se o valor for 'indefinido', a confissão 'se' não será aprovada.
Oskar Szura 15/10
3
Isso combina variáveis ​​que não estão definidas (que lançam um ReferenceError na avaliação), que são diferentes das variáveis ​​com o undefinedvalor.
Qantas 94 Heavy
2
Eu recebi o mesmo erro aqui. if (x), if (! x), if (!! x) lançarão erro se x for indefinido.
shaosh
if(value === 0) gameOver(); ;)
Madbreaks
Essa resposta também está errada porque retorna false quando valueé zero, o que não é o que a op está procurando.
Madbreaks
17

Esta verificação de condição

if (!!foo) {
    //foo is defined
}

é tudo o que você precisa.

JerryP
fonte
Suponho que este é apenas um trecho. Mas ifjá faz uma verificação falsa, que apenas converte em um booleano. Ele pega alguns casos que um normal if(foo)não pega?
Daan van Hulst
1
Isso é perfeito para quando você precisa de algo em linha, por exemplo, eu preciso de um atributo de reação (chamado ativo) que seja verdadeiro quando uma string não estiver vazia - uma instrução if seria um exagero para que eu possa apenas usaractive={!!foo}
Ben Kolya Mansley
16

! verifique se há cadeias vazias (""), nulas, indefinidas, falsas e o número 0 e NaN. Digamos, se uma string estiver vazia, var name = ""ela console.log(!name)retornará true.

function isEmpty(val){
  return !val;
}

essa função retornará true se val estiver vazio, nulo, indefinido, falso, o número 0 ou NaN .

OU

De acordo com o domínio do seu problema, você pode usar apenas como !valou !!val.

Arif
fonte
Isso realmente não diz se a variável está vazia, pois false e 0 podem ser valores válidos e não constituem um valor vazio. O valor de ter uma função isEmpty seria garantir que os valores que você espera que sejam vazios retornem verdadeiro. na minha opinião nulo, indefinido, NaN e uma string vazia são os valores que fazem sentido como vazios.
Corey Young
9
Por que usar isEmpty(val)se você pudesse fazer !val?
Allen Linatoc
É com você. Você pode usá-lo para aumentar a legibilidade. Caso contrário, se você acha que a equipe em que trabalha é mais avançada, então você pode usar apenas !valou de !!valacordo com o domínio do seu problema.
Arif #
15

Uma solução que eu gosto muito:

Vamos definir que uma variável em branco é null, ou undefined, ou se tem comprimento, é zero, ou se é um objeto, não possui chaves:

function isEmpty (value) {
  return (
    // null or undefined
    (value == null) ||

    // has length and it's zero
    (value.hasOwnProperty('length') && value.length === 0) ||

    // is an Object and has no keys
    (value.constructor === Object && Object.keys(value).length === 0)
  )
}

Devoluções:

  • verdade: undefined , null, "", [],{}
  • false: true , false, 1, 0, -1, "foo", [1, 2, 3],{ foo: 1 }
Alexandre Magro
fonte
14

Você está exagerando um pouco. Para verificar se uma variável não recebe um valor, você só precisa verificar se é indefinido e nulo.

function isEmpty(value){
    return (typeof value === "undefined" || value === null);
}

Isso pressupõe que 0, ""e objetos (mesmo objeto e matriz vazios) são "valores" válidos.

tcooc
fonte
10

Se você preferir javascript simples, tente o seguinte:

  /**
   * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
   * length of `0` and objects with no own enumerable properties are considered
   * "empty".
   *
   * @static
   * @memberOf _
   * @category Objects
   * @param {Array|Object|string} value The value to inspect.
   * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
   * @example
   *
   * _.isEmpty([1, 2, 3]);
   * // => false
   *
   * _.isEmpty([]);
   * // => true
   *
   * _.isEmpty({});
   * // => true
   *
   * _.isEmpty('');
   * // => true
   */

function isEmpty(value) {
    if (!value) {
      return true;
    }
    if (isArray(value) || isString(value)) {
      return !value.length;
    }
    for (var key in value) {
      if (hasOwnProperty.call(value, key)) {
        return false;
      }
    }
    return true;
  }

Caso contrário, se você já estiver usando sublinhado ou lodash, tente:

_.isEmpty(value)
l3x
fonte
3
Já experimentou o seu código. Recebo uma mensagem de erro no console que diz: "Erro de referência não capturado: isArray () não está definido". Caso contrário, seria ótimo se funcionasse.
Crmprogdev 22/10/2015
11
No caso de lodash, pelo menos, _.isNilé a função que você está procurando, não _.isEmpty. documentação isNil , documentação
isEmpty
Isso falharia se o valor fosse booleano e tivesse o valor true.
precisa saber é o seguinte
3
O javascript comum não tem isArrayou isStringfunciona no window.
GFoley83
@ GFoley83 - Você me pegou! Eu tenho meus motivos para não usar o Windows. Na verdade, abordo o tópico do capítulo que fala sobre a história e a progressão das linguagens de software. Informações mais relevantes provavelmente serão a discussão / código que demonstra o tratamento de erros monádicos em meu livro, Aprenda a programação funcional no Go. Felicidades!
L3x 5/11
9

Aqui está o meu - retorna true se o valor for nulo, indefinido, etc ou em branco (ou seja, contém apenas espaços em branco):

function stringIsEmpty(value) {

    return value ? value.trim().length == 0 : true;

}
DavidWainwright
fonte
1
Eu fiz um teste em vários métodos aqui. Com uma verificação indefinida, sua função funciona muito bem. Então, eu uso if (typeof value! == 'undefined' &&! IsEmpty (value)) OU, se você realmente deseja verificar se está vazio, pode usar if (typeof value === 'undefined' || IsEmpty2 (value) ) Isso funcionará para nulo; Indefinido; 0; ""; ""; false
RationalRabbit
6
return val || 'Handle empty variable'

é uma maneira muito agradável e limpa de lidar com isso em muitos lugares, também pode ser usado para atribuir variáveis

const res = val || 'default value'
cubefox
fonte
Um monte de lugares, mas não quando o padrão é truee você está tentando fornecer ou devolver um valdos false.
Molomby 20/03/19
@Molomby que é um caso vantagem muito específica, mas mesmo isso é facilmente manipuladoconst res = falsyValue ? true : falsyValue
cubefox
5

Se a variável não tiver sido declarada, você não poderá testar indefinidamente usando uma função, pois receberá um erro.

if (foo) {}
function (bar) {}(foo)

Ambos irão gerar um erro se foo não tiver sido declarado.

Se você quiser testar se uma variável foi declarada, você pode usar

typeof foo != "undefined"

se você quiser testar se foo foi declarado e tem um valor, você pode usar

if (typeof foo != "undefined" && foo) {
    //code here
}
herostwist
fonte
5

Para verificar o valor padrão

function typeOfVar (obj) {
      return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
function isVariableHaveDefaltVal(variable) {
    if ( typeof(variable) === 'string' ) {  // number, boolean, string, object 
        console.log(' Any data Between single/double Quotes is treated as String ');        
        return (variable.trim().length === 0) ? true : false;
    }else if ( typeof(variable) === 'boolean' ) {
      console.log('boolean value with default value \'false\'');
        return (variable === false) ? true : false;
    }else if ( typeof(variable) === 'undefined' ) {
        console.log('EX: var a; variable is created, but has the default value of undefined.'); 
        return true;
    }else if ( typeof(variable) === 'number' ) { 
        console.log('number : '+variable);
        return (variable === 0 ) ? true : false;
    }else if ( typeof(variable) === 'object' ) {
   //   -----Object-----
        if (typeOfVar(variable) === 'array' && variable.length === 0) {
            console.log('\t Object Array with length = ' + [].length); // Object.keys(variable)
            return true;
        }else if (typeOfVar(variable) === 'string' && variable.length === 0 ) {
            console.log('\t Object String with length = ' + variable.length);
            return true;
        }else if (typeOfVar(variable) === 'boolean' ) {
            console.log('\t Object Boolean = ' + variable);
            return (variable === false) ? true : false;
        }else if (typeOfVar(variable) === 'number' ) {
            console.log('\t Object Number = ' + variable);
            return (variable === 0 ) ? true : false;
        }else if (typeOfVar(variable) === 'regexp' && variable.source.trim().length === 0 ) {
       console.log('\t Object Regular Expression : ');
        return true;
        }else if (variable === null) {
       console.log('\t Object null value');
        return true;
        }
    }
    return false;
}
var str = "A Basket For Every Occasion";
str = str.replace(/\s/g, "-");
//The "g" flag in the regex will cause all spaces to get replaced.

verifique o resultado:

isVariableHaveDefaltVal(' '); // string          
isVariableHaveDefaltVal(false); // boolean       
var a;           
isVariableHaveDefaltVal(a);               
isVariableHaveDefaltVal(0); // number             
isVariableHaveDefaltVal(parseInt('')); // NAN isNAN(' '); - true         
isVariableHaveDefaltVal(null);              
isVariableHaveDefaltVal([]);               
isVariableHaveDefaltVal(/ /);              
isVariableHaveDefaltVal(new Object(''));               
isVariableHaveDefaltVal(new Object(false));            
isVariableHaveDefaltVal(new Object(0)); 
typeOfVar( function() {} );

Eu usei a função @Vix () para verificar o objeto de qual tipo.

usando instansof «

var prototypes_or_Literals = function (obj) {
    switch (typeof(obj)) {
        // object prototypes
        case 'object':
            if (obj instanceof Array)
                return '[object Array]';
            else if (obj instanceof Date)
                return '[object Date]';
            else if (obj instanceof RegExp)
                return '[object regexp]';
            else if (obj instanceof String)
                return '[object String]';
            else if (obj instanceof Number)
                return '[object Number]';

            else
                return 'object';
        // object literals
        default:
            return typeof(obj);
    }   
};
output test «
prototypes_or_Literals( '' ) // "string"
prototypes_or_Literals( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]"        
Yash
fonte
Operadores de comparação verifica == [Dados]. === [Dados, tipo de objeto] Os números JS são sempre armazenados como números de ponto flutuante de precisão dupla, seguindo o padrão internacional IEEE 754. // Number Type [int, float literals ] var int = 77; var float = 77.7; console.log( int.toFixed(10) + '\t' + float.toFixed(10) ); // Object Type var number = new Number( 77 ); if( int != float ) console.log('Data Not Equal'); if( int == number && int !== number ) console.log('Data is Equal & Types vary');
Yash
5
function isEmpty(obj) {
    if (typeof obj == 'number') return false;
    else if (typeof obj == 'string') return obj.length == 0;
    else if (Array.isArray(obj)) return obj.length == 0;
    else if (typeof obj == 'object') return obj == null || Object.keys(obj).length == 0;
    else if (typeof obj == 'boolean') return false;
    else return !obj;
}

No ES6 com corte para manipular cadeias de espaços em branco:

const isEmpty = value => {
    if (typeof value === 'number') return false
    else if (typeof value === 'string') return value.trim().length === 0
    else if (Array.isArray(value)) return value.length === 0
    else if (typeof value === 'object') return value == null || Object.keys(value).length === 0
    else if (typeof value === 'boolean') return false
    else return !value
}
jales cardoso
fonte
1
ótima função, obrigado! lida com todo tipo de valor - os números são deixados de fora em todas as outras soluções!
Fabian von Ellerts
1
@FabianvonEllerts Por favor, não tente editar código adicional na resposta de outra pessoa. Poste-a como sua própria resposta, como um comentário abaixo da resposta ou solicite em um comentário que elas atualizem a resposta.
TylerH
5

Pode ser útil.

Todos os valores na matriz representam o que você deseja ser (nulo, indefinido ou outras coisas) e você pesquisa o que deseja nela.

var variablesWhatILookFor = [null, undefined, ''];
variablesWhatILookFor.indexOf(document.DocumentNumberLabel) > -1
ddagsan
fonte
2
você poderia explicar por favor? o que está acontecendo lá
JoshKisb
A matriz contém algumas variáveis ​​que você assumiu como vazias.
ddagsan
@ JoshKisb todos os valores na matriz representam o que você deseja ser (nulo, indefinido ou outras coisas) e você pesquisa o que deseja nele.
ddagsan
1
@ddagsan Enquanto JoshKisb pode apreciar a sua resposta, você deve colocar a sua explicação na sua resposta, em vez de nos comentários
Nick
4

Se você estiver usando TypeScripte não quiser contabilizar "esses valores são false" , esta é a solução para você:

Primeiro: import { isNullOrUndefined } from 'util';

Então: isNullOrUndefined(this.yourVariableName)

Observação: como mencionado abaixo, isso agora está obsoleto, use em seu value === undefined || value === nulllugar. ref .

Barba Negra
fonte
2
Eu pensei que isso era legal, então inicialmente não votei, mas é uma coisa do Node.js que foi preterida. O arquivo de definições de tipo diz: # /** @deprecated since v4.0.0 - use "value === null || value === undefined" instead. */
atomictom
@atomictom Eu pensei que era uma typescriptcoisa. Você pode fornecer o link da documentação?
Blackbeard
Aqui: nodejs.org/api/util.html#util_util_isnullorundefined_object . Além disso: "Eu pensei que isso era legal, então eu inicialmente votei " que deveria ler :) #
atomictom
Por que o depreciaria uma coisa simples e útil como essa? geeeeees.
ticktock
3

Vácuo

Não recomendo tentar definir ou usar uma função que calcule se algum valor no mundo inteiro está vazio. O que realmente significa ser "vazio"? Se eu tiver let human = { name: 'bob', stomach: 'empty' }, devo isEmpty(human)voltar true? Se eu tiver let reg = new RegExp('');, devo isEmpty(reg)voltar true? Que isEmpty([ null, null, null, null ])tal - esta lista contém apenas o vazio, então a lista em si está vazia? Quero apresentar aqui algumas notas sobre "vacuidade" (uma palavra intencionalmente obscura, para evitar associações pré-existentes) em javascript - e quero argumentar que "vacuidade" em valores de javascript nunca deve ser tratada genericamente.


Veracidade / falsidade

Para decidir como determinar a "vacuidade" dos valores, precisamos acomodar o senso inerente e inerente ao javascript de saber se os valores são "verdadeiros" ou "falsos". Naturalmente, nulle undefinedambos são "falsos". Menos naturalmente, o número 0(e nenhum outro número, exceto NaN) também é "falso". Menos naturalmente: ''é falso, mas []e {}(e new Set(), e new Map()) são verdadeiros - embora todos pareçam igualmente vazios!


Nulo vs Indefinido

Há também alguma discussão sobre nullvs undefined- nós realmente precisamos de ambos para expressar a vacuidade em nossos programas? Pessoalmente, evito que as letras u, n, d, e, f, i, n, e, d apareçam no meu código nessa ordem. Eu sempre uso nullpara significar "vazio". Novamente, porém, precisamos acomodar o senso inerente de javascript de como nulle undefineddiferir:

  • Tentar acessar uma propriedade inexistente fornece undefined
  • Omitir um parâmetro ao chamar uma função resulta nesse parâmetro recebendo undefined :

let f = a => a;
console.log(f('hi'));
console.log(f());

  • Parâmetros com valores padrão recebem o padrão somente quando fornecidos undefined, não null:

let f = (v='hello') => v;
console.log(f(null));
console.log(f(undefined));


Vacuidade não genérica

Acredito que a vacuidade nunca deve ser tratada de maneira genérica. Em vez disso, devemos sempre ter o rigor para obter mais informações sobre nossos dados antes de determinar se estão vazios - eu faço isso principalmente verificando com que tipo de dados estou lidando:

let isType = (value, Cls) => {
  try {
    return Object.getPrototypeOf(value).constructor === Cls;
  } catch(err) {
    return false;
  }
};

Observe que essa função ignora o polimorfismo - espera valueser uma instância direta de Cls, e não uma instância de uma subclasse de Cls. eu evitoinstanceof por duas razões principais:

  • ([] instanceof Object) === true ("Uma matriz é um objeto")
  • ('' instanceof String) === false ("Uma String não é uma String")

Observe que Object.getPrototypeOfé usado para evitar um caso como let v = { constructor: String };A isTypefunção ainda retorna corretamente para isType(v, String)(false) e isType(v, Object)(true).

No geral, eu recomendo usar esta isTypefunção junto com estas dicas:

  • Minimize a quantidade de valores de processamento de código de tipo desconhecido. Por exemplo, pois let v = JSON.parse(someRawValue);, nossa vvariável agora é do tipo desconhecido. O mais cedo possível, devemos limitar nossas possibilidades. A melhor maneira de fazer isso pode ser exigindo um tipo específico: por exemplo if (!isType(v, Array)) throw new Error('Expected Array');- essa é uma maneira muito rápida e expressiva de remover a natureza genérica ve garantir que seja sempre uma Array. Às vezes, porém, precisamos permitir vque sejam de vários tipos. Nesses casos, devemos criar blocos de código onde vnão são mais genéricos, o mais cedo possível:

if (isType(v, String)) {
  /* v isn't generic in this block - It's a String! */
} else if (isType(v, Number)) {
  /* v isn't generic in this block - It's a Number! */
} else if (isType(v, Array)) {
  /* v isn't generic in this block - it's an Array! */
} else {
  throw new Error('Expected String, Number, or Array');
}

  • Sempre use "listas brancas" para validação. Se você precisar que um valor seja, por exemplo, String, Number ou Array, verifique essas 3 possibilidades "brancas" e gere um Erro se nenhuma das 3 estiver satisfeita. Devemos ser capazes de ver que a verificação de possibilidades "negros" não é muito útil: dizer que escrever if (v === null) throw new Error('Null value rejected');- isso é ótimo para garantir que nullvalores não passar por isso, mas se um valor faz passar por isso, ainda sabemos pouco nada sobre isso. Um valor vque passa nessa verificação nula ainda é MUITO genérico - é tudo menosnull ! As listas negras dificilmente dissipam a genérica.
  • A menos que seja um valor null, nunca considere "um valor vazio". Em vez disso, considere "um X que é vazio". Essencialmente, nunca considere fazer algo assim if (isEmpty(val)) { /* ... */ }- não importa como essa isEmptyfunção seja implementada (eu não quero saber ...), não é significativo! E é genérico demais! A vacuidade deve ser calculada apenas com o conhecimento do valtipo. As verificações de vacuidade devem ter a seguinte aparência:

    • "Uma string, sem caracteres": if (isType(val, String) && val.length === 0) ...
    • "Um objeto, com 0 adereços": if (isType(val, Object) && Object.entries(val).length === 0) ...
    • "Um número igual ou menor que zero": if (isType(val, Number) && val <= 0) ...
    • "Uma matriz, sem itens": if (isType(val, Array) && val.length === 0) ...

    • A única exceção é quando nullé usado para significar determinada funcionalidade. Nesse caso, é significativo dizer: "Um valor vazio":if (val === null) ...

Gershom
fonte
Vejo que você pensou um pouco:>
Rui Marques
3

Tente com lógica diferente . Você pode usar o código abaixo para verificar todas as quatro (4) condições para validação, como não nulo, não em branco, não indefinido e não zero, use apenas este código (! (! (Variável))) em javascript e jquery.

function myFunction() {
    var data;  //The Values can be like as null, blank, undefined, zero you can test

    if(!(!(data)))
    {
        alert("data "+data);
    } 
    else 
    {
        alert("data is "+data);
    }
}
Ravikant
fonte
3

Dê uma olhada no novo operador coalescente ECMAScript Nullish

Você pode pensar nesse recurso - o ??operador - como uma maneira de "retornar" a um valor padrão ao lidar com nullou undefined.

let x = foo ?? bar();

Novamente, o código acima é equivalente ao seguinte.

let x = (foo !== null && foo !== undefined) ? foo : bar();
Daniel Eduardo Delgado Diaz
fonte
2
function isEmpty(val){
    return !val;
}

mas essa solução é projetada em excesso, se você não quiser modificar a função posteriormente para necessidades do modelo de negócios, será mais fácil usá-la diretamente no código:

if(!val)...
Luca C.
fonte
2
var myNewValue = myObject && myObject.child && myObject.child.myValue;

Isso nunca gera um erro. Se myObject , child ou myValue for nulo, myNewValue será nulo. Nenhum erro será gerado

Keith Blanchard
fonte
2

Para todos que vêm aqui por ter perguntas semelhantes, o seguinte funciona muito bem e eu o tenho em minha biblioteca nos últimos anos:

(function(g3, $, window, document, undefined){
   g3.utils = g3.utils || {};
/********************************Function type()********************************
* Returns a lowercase string representation of an object's constructor.
* @module {g3.utils}
* @function {g3.utils.type}
* @public
* @param {Type} 'obj' is any type native, host or custom.
* @return {String} Returns a lowercase string representing the object's 
* constructor which is different from word 'object' if they are not custom.
* @reference http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
* http://stackoverflow.com/questions/3215046/differentiating-between-arrays-and-hashes-in-javascript
* http://javascript.info/tutorial/type-detection
*******************************************************************************/
g3.utils.type = function (obj){
   if(obj === null)
      return 'null';
   else if(typeof obj === 'undefined')
      return 'undefined';
   return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
};
}(window.g3 = window.g3 || {}, jQuery, window, document));
centuriano
fonte
2

Se você deseja evitar ser verdadeiro se o valor for qualquer um dos seguintes, de acordo com a resposta de jAndy :

  • nulo
  • Indefinido
  • NaN
  • sequência vazia ("")
  • 0 0
  • falso

Uma solução possível que pode evitar a obtenção de valores reais é a seguinte:

function isUsable(valueToCheck) {
    if (valueToCheck === 0     || // Avoid returning false if the value is 0.
        valueToCheck === ''    || // Avoid returning false if the value is an empty string.
        valueToCheck === false || // Avoid returning false if the value is false.
        valueToCheck)             // Returns true if it isn't null, undefined, or NaN.
    {
        return true;
    } else {
        return false;
    }
}

Seria usado da seguinte maneira:

if (isUsable(x)) {
    // It is usable!
}
// Make sure to avoid placing the logical NOT operator before the parameter (isUsable(!x)) and instead, use it before the function, to check the returned value.
if (!isUsable(x)) {
    // It is NOT usable!
}

Além desses cenários, convém retornar false se o objeto ou a matriz estiver vazia:

Você faria dessa maneira:

function isEmptyObject(valueToCheck) {
    if(typeof valueToCheck === 'object' && !Object.keys(valueToCheck).length){
        // Object is empty!
        return true;
    } else {
        // Object is not empty!
        return false;
    }
}

function isEmptyArray(valueToCheck) {
    if(Array.isArray(valueToCheck) && !valueToCheck.length) {
        // Array is empty!
        return true;
    } else {
        // Array is not empty!
        return false;
    }
}

Se você deseja verificar todas as strings de espaço em branco (""), faça o seguinte:

function isAllWhitespace(){
    if (valueToCheck.match(/^ *$/) !== null) {
        // Is all whitespaces!
        return true;
    } else {
        // Is not all whitespaces!
        return false;
    }
}

Nota: hasOwnPropertyretorna true para cadeias vazias, 0, false, NaN, nula e indefinida, se a variável foi declarada como uma delas, portanto, pode não ser o melhor para usar. A função pode ser modificada para usá-la para mostrar que foi declarada, mas não é utilizável.

yaharga
fonte
2

Código no GitHub

const isEmpty = value => (
  (!value && value !== 0 && value !== false)
  || (Array.isArray(value) && value.length === 0)
  || (isObject(value) && Object.keys(value).length === 0)
  || (typeof value.size === 'number' && value.size === 0)

  // `WeekMap.length` is supposed to exist!?
  || (typeof value.length === 'number'
      && typeof value !== 'function' && value.length === 0)
);

// Source: https://levelup.gitconnected.com/javascript-check-if-a-variable-is-an-object-and-nothing-else-not-an-array-a-set-etc-a3987ea08fd7
const isObject = value =>
  Object.prototype.toString.call(value) === '[object Object]';

Testes do pobre homem 😁

const test = () => {
  const run = (label, values, expected) => {
    const length = values.length;
    console.group(`${label} (${length} tests)`);
    values.map((v, i) => {
      console.assert(isEmpty(v) === expected, `${i}: ${v}`);
    });
    console.groupEnd();
  };

  const empty = [
    null, undefined, NaN, '', {}, [],
    new Set(), new Set([]), new Map(), new Map([]),
  ];
  const notEmpty = [
    ' ', 'a', 0, 1, -1, false, true, {a: 1}, [0],
    new Set([0]), new Map([['a', 1]]),
    new WeakMap().set({}, 1),
    new Date(), /a/, new RegExp(), () => {},
  ];
  const shouldBeEmpty = [
    {undefined: undefined}, new Map([[]]),
  ];

  run('EMPTY', empty, true);
  run('NOT EMPTY', notEmpty, false);
  run('SHOULD BE EMPTY', shouldBeEmpty, true);
};

Resultado dos testes:

EMPTY (10 tests)
NOT EMPTY (16 tests)
SHOULD BE EMPTY (2 tests)
  Assertion failed: 0: [object Object]
  Assertion failed: 1: [object Map]
Pascal Polleunus
fonte
ótima função, todas as outras respostas aqui tiveram vários problemas que o seu parece abordar, eu gostaria de ter encontrado antes de escrever o meu: pensei que você gostaria de dar uma olhada no meu trabalho stackoverflow.com/ questions / 5515310 /… ambas as funções parecem ter exatamente a mesma saída, mas reduzi um pouco o código. Por favor, deixe-me saber se eu perdi alguma coisa.
Sean Bannister em
Try Você tentou meus "testes do pobre homem"? Acho que acabei adicionando mais testes na função para casos especiais como Map, WeakMap e talvez também Date, RegExp. Você tem certeza do seu value.constructor === Object? Verifique isso .
Pascal Polleunus 23/04
Sim, eu executei seus testes, obrigado por eles, ambas as nossas funções retornam os mesmos resultados com os dois testes. Fico me perguntando se estou perdendo alguma coisa fora desses casos de teste. Eu acredito que value.constructor === Objectestá tudo bem, em javascript, se as instruções OR OR têm ordem de execução, para que a instrução OR seja executada apenas se a anterior não retornar TRUE e já tivermos verificado Null. De fato, o único objetivo dessa última instrução OR é detectar {}e garantir que ela não retorne VERDADEIRO por coisas que não deveria.
Sean Bannister
1

Isso verificará se a variável de aninhamento indeterminado é indefinida

function Undef(str) 
{
  var ary = str.split('.');
  var w = window;
  for (i in ary) {
    try      { if (typeof(w = w[ary[i]]) === "undefined") return true; }
    catch(e) { return true; }
  }
  return false;
}

if (!Undef("google.translate.TranslateElement")) {

O item acima verifica se a função de tradução do Google TranslateElement existe. Isso é equivalente a:

if (!(typeof google === "undefined" 
 || typeof google.translate === "undefined" 
 || typeof google.translate.TranslateElement === "undefined")) {
rickdog
fonte
1

O operador de encadeamento opcional fornece uma maneira de simplificar o acesso a valores por meio de objetos conectados quando é possível que uma referência ou função seja indefinida ou nula.

let customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls" // detailed address is unknown
  }
};
let customerCity = customer.details?.address?.city;

O operador coalescente nulo pode ser usado após o encadeamento opcional para criar um valor padrão quando nenhum foi encontrado:

let customer = {
  name: "Carl",
  details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city
Sunny Sultan
fonte
1
function notEmpty(value){
  return (typeof value !== 'undefined' && value.trim().length);
}

também verificará os espaços em branco ('') junto com o seguinte:

  • nulo, indefinido, NaN, vazio, sequência (""), 0, falso
Hassan Ali Shahzad
fonte
0

Eu acho que usando o? operador é um pouco mais limpo.

var ? function_if_exists() : function_if_doesnt_exist();
Pedro Pereira
fonte