¿Existe una función estándar para verificar variables nulas, indefinidas o en blanco en JavaScript?

2261

¿Hay una función universal de JavaScript que comprueba que una variable tiene un valor y asegura que no es undefinedo null? Tengo este código, pero no estoy seguro si cubre todos los casos:

function isEmpty(val){
    return (val === undefined || val == null || val.length <= 0) ? true : false;
}
Alex
fuente
55
posible duplicado de ¿Cómo verifica si hay una cadena vacía en JavaScript?
Dour High Arch
78
Protip, nunca lo hagas (truthy statement) ? true : false;. Solo hazlo (truthy statement);.
David Baucum
55
@GeorgeJempty no es un dup, ya que la otra respuesta pregunta sobre cadenas en particular, mientras que esta pregunta sobre variables .
Madbreaks 01 de
2
Cualquier respuesta correcta a esta pregunta se basa completamente en cómo define "en blanco".
Madbreaks
3
@ Jay No duele nada en cuanto a la ejecución de su código. Es demasiado detallado. No dirías: "¿Tienes hambre es verdad?" Simplemente "¿Tienes hambre"? Entonces en el código solo di en if (hungry) …lugar de if (hungry === true) …. Como todas las cosas de codificación de esta manera, es solo cuestión de gustos. Más específico al ejemplo proporcionado por el OP, está diciendo aún más detalladamente: "Si es cierto, entonces cierto, si no es falso" Pero si es cierto, entonces ya es cierto. Y, si es falso, ya es falso. Esto es similar a decir "Si tienes hambre, entonces tienes, y si no, entonces no tienes".
David Baucum

Respuestas:

4380

Simplemente puede verificar si la variable tiene un truthyvalor o no. Eso significa

if( value ) {
}

evaluará truesi novalue es :

  • nulo
  • indefinido
  • Yaya
  • cuerda vacía ("")
  • 0 0
  • falso

La lista anterior representa todos los falsyvalores posibles en ECMA- / Javascript. Encuéntrelo en la especificación en la ToBooleansección.

Además, si no sabe si existe una variable (es decir, si se declaró ), debe consultar con el typeofoperador. Por ejemplo

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

Si puede estar seguro de que una variable se declara al menos, debe verificar directamente si tiene un truthyvalor como el que se muestra arriba.

Más información: http://typeofnan.blogspot.com/2011/01/typeof-is-fast.html

jAndy
fuente
110
¿Qué pasa si el valor es un falso booleano que se pretendía? A veces, desea dar un valor predeterminado si no hay ningún valor, que no funcionará si se pasa booleano falso.
TruMan1
100
@ TruMan1: en tal caso (donde su lógica dicta la validación) tiene que ir como if( value || value === false ). Lo mismo ocurre con todos los valores falsos , debemos validarlos explícitamente.
jAndy
28
Excepto si el valor es una matriz. La interpretación de truthypodría ser engañosa. En ese caso, deberíamos verificar value.length != 0una matriz no vacía.
usuario
12
Sólo quiero añadir que si se siente la ifconstrucción es sintácticamente demasiado pesado, se puede utilizar el operador ternario, así: var result = undefined ? "truthy" : "falsy". O si lo que desea es coaccionar a un valor booleano, utilice el !!operador, por ejemplo !!1 // true, !!null // false.
KFL
77
También tenga en cuenta que esto no buscará cadenas que solo contengan caracteres de espacio en blanco.
Christophe Roussy el
222

El método detallado para verificar si el valor es indefinido o nulo es:

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

También puede usar el ==operador, pero se espera que uno conozca todas las reglas :

return value == null; // also returns true if value is undefined
Salman A
fuente
33
Comprobación de la única nullo undefinedse puede hacer de esta manera: if (value == null). Cuidado con el ==operador que coacciona. Si marca así if (value === null || value === undefined), olvidó / no sabe cómo Javascript coacciona. webreflection.blogspot.nl/2010/10/…
Christiaan Westerbeek
32
@ChristiaanWesterbeek: su punto que arg == nullproduce los mismos resultados que arg === undefined || arg === null. Sin embargo, considero que el último ejemplo es más legible.
Salman A
10
arg == nullEs bastante común en mi experiencia.
Bryan Downing
8
return value === (void 0)es más seguro que probar contra el undefinedcual bien puede ser una variable legítima en alcance, lamentablemente.
x0n
44
@Sharky Hay una diferencia entre una variable que no está definida y una variable no declarada: lucybain.com/blog/2014/null-undefined-undeclared
Christiaan Westerbeek
80
function isEmpty(value){
  return (value == null || value.length === 0);
}

Esto volverá cierto para

undefined  // Because undefined == null

null

[]

""

y funciones de argumento cero ya que una función lengthes el número de parámetros declarados que toma.

Para no permitir la última categoría, es posible que solo desee verificar las cadenas en blanco

function isEmpty(value){
  return (value == null || value === '');
}
Mike Samuel
fuente
77
undefined == nullperoundefined !== null
Ian Boyd
2
@IanBoyd eso es porque estás comparando == a ===. esto significa que undefined == null (true) undefined! = null (false) undefined === null (false) undefined! == null (true) sería mejor dar un poco más de información para ser útil y empujar a las personas en la dirección correcta. moz doc sobre la diferencia developer.mozilla.org/en-US/docs/Web/JavaScript/…
Corey Young
43

Este es el control más seguro y no lo he visto publicado aquí exactamente así:

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

Cubrirá casos en los que el valor nunca se definió, y también alguno de estos:

  • nulo
  • undefined (el valor de undefined no es lo mismo que un parámetro que nunca se definió)
  • 0 0
  • "" (cuerda vacía)
  • falso
  • Yaya

Editado: Cambiado a igualdad estricta (! ==) porque ya es la norma;)

guya
fuente
10
No voté en contra, pero con respecto a la comparación estricta de igualdad, la regla general es que, a menos que necesite una conversión de tipo implícita, se debe usar una comparación estricta.
J.Steve
2
Gracias por tu comentario Steve. Esa regla general está bien. Solo espero que las personas comprendan por qué usan una u otra. Cada vez que mires, ppl estará encantado de predicarte sobre "siempre usar estrictamente", como si fuera lo más importante en Javascript. He visto demasiados casos como if (val! == null) que obviamente conducen a un resultado no deseado. Está bien decirlo cuando tenga dudas: use estrictamente, pero es mejor no tener dudas.
guya
66
Creo que el punto aquí es que esperamos que el typeofoperador devuelva una cadena, por lo que usar la estricta verificación de igualdad es técnicamente más preciso, más específico y más rápido. Entonces, realmente, no hay razón para usar la comparación suelta, y no al revés. También val !== nulles perfectamente válido en muchos casos, lo hago todo el tiempo. Estoy de acuerdo con su argumento de no conformidad, pero creo que este es un mal ejemplo para hacerlo. No estoy tratando de hacerte troll.
Bryan Downing
Gracias por tu comentario Bryan, Usas val! == null porque sabes lo que estás haciendo. Un principiante querrá tener una alternativa a cuando val es falso. Pero, val nunca será nulo, será indefinido. Si no escuchara ese consejo de "siempre usar estrictamente", tendrá menos errores. He visto que esto sucede en el código de producción. typeof siempre devuelve una cadena y la diferencia de velocidad será redundante. Entonces, el único argumento para usar estricto en el caso anterior es la consistencia. He dicho "No hay necesidad de igualdad estricta". No significa que no pueda hacerlo si lo desea o si hace que su código sea más consistente.
guya
28

Puede encontrar útil la siguiente función:

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

O en ES7 (comenta si hay más mejoras)

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

"Tenga en cuenta que el operador de enlace (: :) no forma parte de ES2016 (ES7) ni de ninguna edición posterior del estándar ECMAScript. Actualmente es una propuesta de etapa 0 (strawman) para ser introducido en el lenguaje". - Simon Kjellberg. el autor desea agregar su apoyo a esta hermosa propuesta para recibir la ascensión real.

Vix
fuente
+1 es útil conocer el objeto de tipo 'regexp' , 'array' y 'function'
Yash
@Vix, ¿por qué la versión ES7 es mejor?
GollyJer
No lo era, estaba experimentando con formas más legibles de expresar la misma funcionalidad utilizando: asignación de desestructuración, operador de enlace.
Vix
2
Tenga en cuenta que el operador de enlace ( ::) no forma parte de ES2016 (ES7) ni de ninguna edición posterior del estándar ECMAScript. Actualmente es una propuesta de etapa 0 (hombre de paja) para ser introducido en el idioma.
Simon Kjellberg
25

La primera respuesta con la mejor calificación es incorrecta. Si el valor no está definido, arrojará una excepción en los navegadores modernos. Tienes que usar:

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

o

if (typeof value  !== "undefined" && value)
krupar
fuente
3
eee ... Creo que esto está mal como si (valor) es suficiente (excepto objetos / matrices vacíos). si el valor es 'indefinido', la confesión 'si' no pasará.
Oskar Szura
3
Esto combina variables que no están definidas (que arrojan un Error de referencia en la evaluación), que son diferentes a las variables con el undefinedvalor.
Qantas 94 Heavy
2
Tengo el mismo error aquí. if (x), if (! x), if (!! x) arrojarán un error si x no está definido.
shaosh
if(value === 0) gameOver(); ;)
Madbreaks
Esta respuesta también es incorrecta porque devuelve falso cuando valuees cero, que no es lo que op está buscando.
Madbreaks
17

Esta comprobación de estado

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

es todo lo que necesitas.

JerryP
fuente
Supongo que esto es solo un fragmento. Pero ifya hace una comprobación falsa, que esto simplemente convierte a un booleano. ¿Captura algún caso que una normal if(foo)no detecta?
Daan van Hulst
1
Esto es perfecto para cuando necesita algo en línea, por ejemplo, necesito un atributo de reacción (llamado activo) que es cierto cuando una cadena no está vacía, una declaración if sería exagerada, así que solo puedo usaractive={!!foo}
Ben Kolya Mansley
16

! compruebe si hay cadenas vacías (""), nulas, indefinidas, falsas y el número 0 y NaN. Digamos, si una cadena está vacía, var name = ""entonces console.log(!name)regresa true.

function isEmpty(val){
  return !val;
}

esta función devolverá verdadero si val está vacío, nulo, indefinido, falso, el número 0 o NaN .

O

De acuerdo con el dominio de su problema, puede usar like !valo !!val.

Arif
fuente
Esto realmente no dice si la variable está vacía, ya que falso y 0 pueden ser valores válidos y no constituyen un valor vacío. El valor de tener una función isEmpty sería asegurarse de que los valores esperados que están vacíos devuelven verdadero. en mi opinión, nulo, indefinido, NaN y una cadena vacía son los valores que tienen sentido como vacío.
Corey Young
99
¿Por qué usar isEmpty(val)si pudieras hacer !val?
Allen Linatoc
Es tu decision. Puede usarlo para aumentar la legibilidad. De lo contrario, si crees que el equipo con el que trabajas es un programador más avanzado, entonces puedes usar solo !valo de !!valacuerdo con el dominio de tu problema.
Arif
15

Una solución que me gusta mucho:

Definamos que una variable en blanco es null, o undefined, o si tiene longitud, es cero, o si es un objeto, no tiene claves:

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)
  )
}

Devoluciones:

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

Estás un poco exagerado. Para verificar si a una variable no se le da un valor, solo necesitaría verificar contra indefinido y nulo.

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

Esto supone 0, ""y los objetos (incluso el objeto vacío y la matriz) son "valores" válidos.

tcooc
fuente
10

Si prefiere JavaScript simple, intente esto:

  /**
   * 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;
  }

De lo contrario, si ya está usando subrayado o lodash, intente:

_.isEmpty(value)
l3x
fuente
3
He intentado tu código. Recibo un mensaje de error en la consola que dice: "Error de referencia no capturado: isArray () no está definido". De lo contrario, sería genial si funcionara.
crmprogdev
11
En el caso de lodash al menos, _.isNiles la función que estás buscando, no _.isEmpty. Documentación isNil
Snixtor
Esto fallaría si el valor es booleano y tiene el valor verdadero.
kalyanbk
3
JavaScript simple no tiene isArrayo isStringfunciones en el window.
GFoley83
@ GFoley83 - ¡Me atrapaste! Tengo mis razones para no usar Windows. De hecho, cubro el tema en el capítulo que habla sobre la historia y la progresión de los lenguajes de software. Es probable que la información más relevante sea la discusión / código que demuestre el manejo de errores monádicos en mi libro, Learn Functional Programming in Go. ¡Salud!
l3x
9

Aquí está el mío: devuelve verdadero si el valor es nulo, indefinido, etc. o en blanco (es decir, contiene solo espacios en blanco):

function stringIsEmpty(value) {

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

}
DavidWainwright
fuente
1
Hice una prueba en varios métodos aquí. Con una comprobación de indefinido, su función funciona muy bien. Así que uso if (typeof value! == 'undefined' &&! IsEmpty (value)) O, si realmente desea verificar si está vacío, puede usar if (typeof value === 'undefined' || IsEmpty2 (value) ) Esto funcionará para nulo; Indefinido; 0; ""; ""; falso
RationalRabbit
6
return val || 'Handle empty variable'

es una forma muy agradable y limpia de manejarlo en muchos lugares, también se puede usar para asignar variables

const res = val || 'default value'
cubefox
fuente
Muchos lugares, pero no cuando el valor predeterminado es truey está tratando de suministrar o devolver uno valde false.
Molomby
@Molomby es un caso límite muy específico, pero incluso eso se maneja fácilmenteconst res = falsyValue ? true : falsyValue
cubefox
5

Si la variable no ha sido declarada, no podrá probar indefinido utilizando una función porque obtendrá un error.

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

Ambos generarán un error si no se ha declarado foo.

Si desea probar si se ha declarado una variable, puede usar

typeof foo != "undefined"

si quieres probar si foo ha sido declarado y tiene un valor que puedes usar

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

Para verificar el valor predeterminado

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.

comprobar 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() {} );

Usé la función @Vix () para verificar el objeto de qué 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
fuente
Operadores de comparación verifica == [Datos]. === [Datos, tipo de objeto] Los números JS siempre se almacenan como números de coma flotante de doble precisión, siguiendo el estándar 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;
}

En ES6 con moldura para manejar cadenas de espacios en blanco:

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
fuente
1
gran función, gracias! maneja todo tipo de valor: ¡los números se omiten en todas las demás soluciones!
Fabian von Ellerts
1
@FabianvonEllerts No intente editar código adicional en la respuesta de otra persona. Publíquelo como su propia respuesta, como un comentario debajo de la respuesta, o solicite en un comentario que actualicen la respuesta ellos mismos.
TylerH
5

Puede ser útil

Todos los valores en la matriz representan lo que quieres ser (nulo, indefinido u otras cosas) y buscas lo que quieres en él.

var variablesWhatILookFor = [null, undefined, ''];
variablesWhatILookFor.indexOf(document.DocumentNumberLabel) > -1
ddagsan
fuente
2
podrías explicar por favor qué está pasando allí
JoshKisb
La matriz contiene alguna variable que asumió como vacía.
ddagsan
@JoshKisb todos los valores en la matriz representan lo que quieres ser (nulo, indefinido u otras cosas) y buscas lo que quieres en él.
ddagsan
1
@ddagsan Si bien JoshKisb puede apreciar tu respuesta, deberías poner tu explicación en tu respuesta en lugar de en los comentarios
Nick
4

Si está utilizando TypeScripty no desea tener en cuenta los "valores que son false" entonces esta es la solución para usted:

Primero: import { isNullOrUndefined } from 'util';

Entonces: isNullOrUndefined(this.yourVariableName)

Tenga en cuenta: como se menciona a continuación, esto ahora está en desuso, use value === undefined || value === nullen su lugar. ref .

Barba Negra
fuente
2
Pensé que esto era genial, así que inicialmente no voté, pero es una cosa de Node.js que ha quedado en desuso. El archivo de definiciones de tipo dice:/** @deprecated since v4.0.0 - use "value === null || value === undefined" instead. */
atomictom
@atomictom Pensé que era una typescriptcosa. ¿Puede por favor proporcionar el enlace de su documentación?
BlackBeard el
Aquí: nodejs.org/api/util.html#util_util_isnullorundefined_object . Además: "Pensé que esto era genial, así que inicialmente voté " que debería leer :)
atomictom
¿Por qué despreciaría una cosa simple útil como esta? geeeeees.
ticktock
3

Vacío

No recomiendo tratar de definir o usar una función que calcule si algún valor en todo el mundo está vacío. ¿Qué significa realmente estar "vacío"? Si tengo let human = { name: 'bob', stomach: 'empty' }, debería isEmpty(human)volver true? Si tengo let reg = new RegExp('');, debería isEmpty(reg)volver true? ¿Qué pasa isEmpty([ null, null, null, null ])? Esta lista solo contiene el vacío, entonces, ¿está vacía la lista misma? Quiero presentar aquí algunas notas sobre "vacuidad" (una palabra intencionalmente oscura, para evitar asociaciones preexistentes) en javascript, y quiero argumentar que la "vacuidad" en los valores de javascript nunca debe tratarse genéricamente.


Verdad / falsedad

Para decidir cómo determinar la "vacuidad" de los valores, necesitamos acomodar el sentido inherente e inherente de JavaScript de si los valores son "verdaderos" o "falsos". Naturalmente, nully undefinedambos son "falsos". Menos naturalmente, el número 0(y ningún otro número excepto NaN) también es "falso". Menos natural: ''es falso, pero []y {}(y new Set(), y new Map()) son verdaderos, ¡aunque todos parecen igualmente vacíos!


Nulo vs Indefinido

También hay una discusión acerca de nullvs undefined: ¿realmente necesitamos ambos para expresar vacío en nuestros programas? Personalmente, evito que las letras u, n, d, e, f, i, n, e, d aparezcan en mi código en ese orden. Siempre uso nullpara significar "vacuidad". Una vez más, sin embargo, necesitamos acomodar el sentido inherente de JavaScript de cómo nully undefineddiferir:

  • Intentar acceder a una propiedad inexistente da undefined
  • Omitir un parámetro al llamar a una función da como resultado que ese parámetro reciba undefined:

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

  • Los parámetros con valores predeterminados reciben el valor predeterminado solo cuando se proporcionan undefined, no null:

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


Vacío no genérico

Creo que la vacuidad nunca debe tratarse de manera genérica. En su lugar, siempre deberíamos tener el rigor de obtener más información sobre nuestros datos antes de determinar si son vacíos; principalmente hago esto verificando qué tipo de datos estoy tratando:

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

Tenga en cuenta que esta función ignora el polimorfismo: espera valueser una instancia directa de Cls, y no una instancia de una subclase de Cls. Evito instanceofpor dos razones principales:

  • ([] instanceof Object) === true ("Una matriz es un objeto")
  • ('' instanceof String) === false ("Una cadena no es una cadena")

Tenga en cuenta que Object.getPrototypeOfse utiliza para evitar un caso como let v = { constructor: String };La isTypefunción todavía regresa correctamente para isType(v, String)(falso) y isType(v, Object)(verdadero).

En general, recomiendo usar esta isTypefunción junto con estos consejos:

  • Minimice la cantidad de valores de procesamiento de código de tipo desconocido. Por ejemplo, para let v = JSON.parse(someRawValue);, nuestra vvariable ahora es de tipo desconocido. Tan pronto como sea posible, debemos limitar nuestras posibilidades. La mejor manera de hacerlo puede ser exigiendo un tipo particular: por ejemplo if (!isType(v, Array)) throw new Error('Expected Array');, esta es una forma realmente rápida y expresiva de eliminar la naturaleza genérica de v, y garantizar que siempre sea así Array. A veces, sin embargo, debemos permitir vser de múltiples tipos. En esos casos, debemos crear bloques de código donde vya no sea genérico, lo antes posible:

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');
}

  • Utilice siempre "listas blancas" para la validación. Si necesita que un valor sea, por ejemplo, una cadena, un número o una matriz, verifique esas 3 posibilidades "blancas" y arroje un error si ninguno de los 3 está satisfecho. Deberíamos poder ver que verificar las posibilidades "negras" no es muy útil: digamos que escribimos if (v === null) throw new Error('Null value rejected');, esto es excelente para garantizar que los nullvalores no se logren, pero si un valor se logra , todavía no lo sabemos nada al respecto. Un valor vque pasa esta verificación nula sigue siendo MUY genérico, ¡es todo menosnull eso ! Las listas negras apenas disipan el genérico.
  • A menos que un valor sea null, nunca considere "un valor vacío". En cambio, considere "una X que está vacía". Esencialmente, nunca considere hacer algo como if (isEmpty(val)) { /* ... */ }: no importa cómo isEmptyse implemente esa función (no quiero saber ...), ¡no tiene sentido! ¡Y es demasiado genérico! La vacuidad solo debe calcularse con conocimiento del valtipo. Los controles de vacío deberían tener este aspecto:

    • "Una cadena, sin caracteres": if (isType(val, String) && val.length === 0) ...
    • "Un objeto, con 0 accesorios": if (isType(val, Object) && Object.entries(val).length === 0) ...
    • "Un número, igual o menor que cero": if (isType(val, Number) && val <= 0) ...
    • "Una matriz, sin elementos": if (isType(val, Array) && val.length === 0) ...

    • La única excepción es cuando nullse usa para indicar cierta funcionalidad. En este caso es significativo decir: "Un valor vacío":if (val === null) ...

Gershom
fuente
Puedo ver que has pensado en esto:>
Rui Marques
3

Probar con lógica diferente . Puede usar el siguiente código para verificar las cuatro (4) condiciones para la validación como no nulo, no en blanco, no indefinido y no cero solo use este código (! (! (Variable))) en javascript y 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
fuente
3

Eche un vistazo al nuevo operador de fusión nula ECMAScript

Puede pensar en esta característica, el ??operador, como una forma de "retroceder" a un valor predeterminado cuando se trata con nullo undefined.

let x = foo ?? bar();

Nuevamente, el código anterior es equivalente al siguiente.

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

pero esta solución está sobredimensionada, si no desea modificar la función más tarde para las necesidades del modelo de negocio, entonces es más limpio usarla directamente en el código:

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

Esto nunca arrojará un error. Si myObject , child o myValue es nulo, myNewValue será nulo. No se arrojarán errores

Keith Blanchard
fuente
2

Para todos los que vienen aquí por tener una pregunta similar, lo siguiente funciona muy bien y lo tengo en mi biblioteca los últimos años:

(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));
centurias
fuente
2

Si desea evitar ser verdadero si el valor es cualquiera de los siguientes, según la respuesta de jAndy :

  • nulo
  • indefinido
  • Yaya
  • cuerda vacía ("")
  • 0 0
  • falso

Una posible solución que podría evitar obtener valores verdaderos es la siguiente:

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;
    }
}

Se usaría de la siguiente manera:

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!
}

Además de esos escenarios, es posible que desee devolver falso si el objeto o la matriz están vacíos:

Lo harías de esta manera:

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;
    }
}

Si desea verificar todas las cadenas de espacios en blanco (""), puede hacer lo siguiente:

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

Nota: hasOwnPropertydevuelve verdadero para cadenas vacías, 0, falso, NaN, nulo e indefinido, si la variable se declaró como cualquiera de ellos, por lo que podría no ser la mejor opción. La función puede modificarse para usarla para mostrar que se declaró, pero no es utilizable.

yaharga
fuente
2

Código en 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]';

Las pruebas del pobre hombre 😁

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);
};

Resultados de la prueba:

EMPTY (10 tests)
NOT EMPTY (16 tests)
SHOULD BE EMPTY (2 tests)
  Assertion failed: 0: [object Object]
  Assertion failed: 1: [object Map]
Pascal Polleunus
fuente
gran función, todas las otras respuestas aquí tenían múltiples problemas que el tuyo parece abordar, solo desearía haberlo encontrado antes de escribir el mío: p pensé que te gustaría echar un vistazo a mi trabajo stackoverflow.com/ preguntas / 5515310 / ... ambas funciones parecen tener exactamente la misma salida, pero he reducido un poco el código. Avísame si me he perdido algo.
Sean Bannister
👍 ¿Intentaste mis "pruebas de Pobre hombre"? Creo que terminé agregando más pruebas en la función para casos especiales como Map, WeakMap y quizás también Date, RegExp. ¿Estás seguro de tu value.constructor === Object? Mira esto .
Pascal Polleunus
Sí, ejecuté sus pruebas, gracias por eso, nuestras dos funciones devuelven los mismos resultados con nuestras dos pruebas. Me sigo preguntando si me falta algo fuera de estos casos de prueba. Creo que value.constructor === Objectestá bien, en javascript las instrucciones IF tienen orden de ejecución, por lo que la instrucción OR solo se ejecutará si la anterior no devolvió VERDADERO y ya lo hemos verificado Null. De hecho, el único propósito de esa última instrucción OR es detectar {}y garantizar que no devuelva VERDADERO por cosas que no debería.
Sean Bannister
1

Esto verificará si la variable de anidamiento indeterminado no está definida

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")) {

Lo anterior verifica si la función de traducción de Google TranslateElement existe. Esto es equivalente a:

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

El operador de encadenamiento opcional proporciona una manera de simplificar el acceso a los valores a través de objetos conectados cuando es posible que una referencia o función sea indefinida o nula.

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

El operador de fusión nulo puede usarse después del encadenamiento opcional para generar un valor predeterminado cuando no se encontró ninguno:

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

también verificará los espacios en blanco ('') junto con lo siguiente:

  • nulo, indefinido, NaN, vacío, cadena (""), 0, falso
Hassan Ali Shahzad
fuente
0

Creo que usando el? El operador está un poco más limpio.

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