¿Cómo pruebo un objeto JavaScript vacío?


3113

Después de una solicitud AJAX, a veces mi aplicación puede devolver un objeto vacío, como:

var a = {};

¿Cómo puedo verificar si ese es el caso?


77
¿Utiliza el script JSON.js? O cualquier otra biblioteca JSON. Luego puede usar la función JSON.encode () para convertir var a cadena y luego probarlo.
Thevs

if( Object.entries(a).length > 0){ //do }
Muhammad Shahzad

Respuestas:


5430

ECMA 5+ :

// because Object.keys(new Date()).length === 0;
// we have to do some additional check
Object.keys(obj).length === 0 && obj.constructor === Object

Sin embargo, tenga en cuenta que esto crea una matriz innecesaria (el valor de retorno de keys).

Pre-ECMA 5:

function isEmpty(obj) {
  for(var prop in obj) {
    if(obj.hasOwnProperty(prop)) {
      return false;
    }
  }

  return JSON.stringify(obj) === JSON.stringify({});
}

jQuery :

jQuery.isEmptyObject({}); // true

lodash :

_.isEmpty({}); // true

Subrayado :

_.isEmpty({}); // true

Hoek

Hoek.deepEqual({}, {}); // true

ExtJS

Ext.Object.isEmpty({}); // true

AngularJS (versión 1)

angular.equals({}, {}); // true

Ramda

R.isEmpty({}); // true

22
Aquí está la prueba de rendimiento entre jQuery y guión bajo jsperf.com/isempty-vs-isemptyobject/6
Mikhail

20
Object.keys(new Date()).length === 0; entonces esta respuesta puede ser engañosa.
cjbarth

66
En lugar de encadenar cosas, también puede aprovechar este hecho: (new Date()).constructor === Dateo viceversa ({}).constructor === Object.
John Nelson

2
angular.equals ({}, {});
Jeremy A. West

11
Object.keys()no verifica propiedades o símbolos no enumerables. Necesitas usar Object.getOwnPropertyNames()y en su Object.getOwnPropertySymbols()lugar. Además, Object.getPrototypeOf()es la forma correcta de obtener el prototipo de un objeto. obj.constructorSe puede forjar fácilmente. Ejemplo: function Foo() {} Foo.prototype.constructor = Object; (new Foo()).constructor === Object // true.
Jesse

863

No hay una manera fácil de hacer esto. Tendrá que recorrer las propiedades explícitamente:

function isEmpty(obj) {
    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
            return false;
    }

    return true;
}

Si el soporte ECMAScript 5 está disponible, puede usar Object.keys()en su lugar:

function isEmpty(obj) {
    return Object.keys(obj).length === 0;
}

56
Esto funciona bien, o más simplemente: function isEmpty (object) {for (var i in object) {return true; } falso retorno; }
Nicholas Kreidberg

36
¿No deberían invertirse verdadero y falso en esta función?
namtax

25
@namtax: no - la función se nombra isEmpty(), por lo que debería regresar falsesi tiene una propiedad
Christoph

66
el objeto vacío extenderá la clase de objeto predeterminada, pero si se modifica el prototipo del objeto, su función simplificada fallará, considere: Object.prototype.a = 'hi'; var obj = {}; alerta (obj.a); // emite "hola" isEmpty (obj) // devuelve falso
venimus

29
No debe usar el segundo ejemplo, ya que es O (n) complejidad de tiempo y O (n) complejidad de espacio, mientras que el primero es O (1).
Brian

572

Para aquellos de ustedes que tienen el mismo problema pero usan jQuery, pueden usar jQuery.isEmptyObject .


43
¡OYE! Solo pasé unas horas depurando problemas de IE 8 solo para descubrir que era jQuery.isEmptyObject lo que causaba el problema. Devuelve verdadero si el objeto está vacío.
MFD3000

162
¿Por qué publica una respuesta que incluye jQuery si la pregunta no es sobre jQuery?
Eru

47
Sé que es un antiguo comentario, pero me pregunto pregunta @ MFD3000, debido a que el docu dice: devuelve true, si el objeto está vacía (como su nombre lo indica)
Александр Фишер

21
incluir jQuery para una tarea tan básica no es lo que yo llamaría la respuesta correcta. Es cierto que hoy en día jQuery es casi omnipresente, pero no debemos olvidar que se basa en un lenguaje muy capaz.
Pablo Mescher

54
El esnobismo típico de JS en estos comentarios. Todos saben que una gran proporción de JavaScript en la web está escrita en jQuery, por lo que es perfectamente aceptable proporcionar una solución aquí para jQuery si ya tiene un método incorporado para probar objetos. Es probable que miles de desarrolladores que buscan ayuda encuentren útil esta respuesta. Nadie dijo que es la única forma de hacerlo. Me doy cuenta de que nadie actúa con elitismo sobre el tipo que publicó una solución para usar underscore.js...
BadHorsie

276

Esta es mi solución preferida:

var obj = {};
return Object.keys(obj).length; //returns 0 if empty or an integer > 0 if non-empty


3
@Jero Franzani: no, no lo hace
nikoskip

La longitud de Object.keys ({}). Es 10 veces más lenta que la opción (para ... en ...). Sugiero evitarla como una forma de comprobar si un objeto está vacío.
davidhadas

10
Object.keys(new Date()).length === 0; entonces esta respuesta puede ser engañosa.
cjbarth

new Date()No es un objeto. nd = new Date(); nd.constructor === Object;resultados en false.
pors

204

Puedes usar Underscore.js .

_.isEmpty({}); // true

19
O podría usar lodash está vacío ( lodash.com/docs#isEmpty ), pero ¿en qué se diferencia de usar una solución jQuery? Aún necesita instalar una biblioteca adicional. Creo que la intención es una solución JavaScript de vainilla.
tfmontague

10
Es diferente si quieres usar JS en el backend con Node.js. Pocas personas querrán usar jQuery (una biblioteca front-end utilizada principalmente para manipulaciones DOM) en el back-end.
Nahn

3
El subrayado @tfmontague es muy común en las aplicaciones de nodo, casi tan omnipresente como jQ en el lado del cliente. Ya tenía subrayado requerido pero no me di cuenta de que tenía esta función
rw-nandemo

55
El guión bajo está siendo reemplazado por lodash. Use eso en su lugar.
retiro

2
Solo tenga cuidado con los tipos de fecha, isEmpty siempre devuelve verdadero para Date, consulte github.com/jashkenas/underscore/issues/445
mentat

116
if(Object.getOwnPropertyNames(obj).length === 0){
  //is empty
}

ver http://bencollier.net/2011/04/javascript-is-an-object-empty/


55
Esto incluye propiedades no enumerables, en caso de que le importe.

La longitud de Object.getOwnPropertyNames ({}). Es 10 veces más lenta que la opción (para ... en ...). Sugiero evitarlo como una forma de probar si un objeto está vacío.
davidhadas

44
Object.getOwnPropertyNames(new Date()).length === 0; entonces esta respuesta puede ser engañosa.
cjbarth

80

¿Qué tal usar JSON.stringify? Está casi disponible en todos los navegadores modernos.

function isEmptyObject(obj){
    return JSON.stringify(obj) === '{}';
}

23
return (JSON.stringify (obj) == '{}')
Vic

26
Esto es lento y la velocidad es importante para este tipo de utilidad. Prueba rápida de rendimiento

1
Esta es una opción muy lenta: sugiero usar la opción (para ... en) en su lugar
davidhadas

2
Y no funciona para objetos que contienen funciones.
Felix Kling

1
También arrojará un error si hay una referencia circular en el objeto. Por lo tanto, es lento, poco confiable y puede arrojar errores y romper todo lo demás. No hay razón para usarlo nunca.
Burak

62

Me encontré con una situación similar. No quería usar JQuery, y quería hacerlo usando Javascript puro.

Y lo que hice fue usar la siguiente condición y funcionó para mí.

var obj = {};
if(JSON.stringify(obj) === '{}') { //This will check if the object is empty
   //Code here..
}

Para no igual a, use esto: JSON.stringify(obj) !== '{}'

Mira este JSFiddle


44
Fallará para los objetos con referencias circulares ya que JSON.stringify específicamente les arroja una excepción.
Pedro Montoto García

1
@ PedroMontotoGarcía Ok, ¿y cómo tendrá un objeto vacío una referencia circular?
KthProg

8
Si el objeto no está vacío (y debería funcionar para ellos también).
Pedro Montoto García

Parece que ya fue mencionado por @Ateszki y es una de las formas más lentas de verificar si un objeto no está vacío.
cwadding

Oh si .. me lo perdí. Me encontré con una situación en la que quería lograr este javascript, y después de pensar un poco lo descubrí de esta manera. @ Ateszki, aunque pensé de la manera que lo hiciste. :-) Por cierto, hubo muchas respuestas sobre esto, así que me perdí tu respuesta.
Anish Nair

60

Antigua pregunta, pero acaba de tener el problema. Incluir JQuery no es realmente una buena idea si su único propósito es verificar si el objeto no está vacío. En cambio, solo profundice en el código de JQuery , y obtendrá la respuesta:

function isEmptyObject(obj) {
    var name;
    for (name in obj) {
        if (obj.hasOwnProperty(name)) {
            return false;
        }
    }
    return true;
}

55
Esto solo es útil si algún otro proceso no ha agregado un prototipo a su objeto base. Para que esto sea realmente viable, debe probar obj.hasOwnProperty (nombre)
mpemburn

1
Esto no agrega nada a la respuesta de Christoph de 2009.
Dan Dascalescu

39

Hay una manera simple si estás en un navegador más nuevo. Object.keys(obj).length == 0


1
¿De dónde keysviene la propiedad?

2
Es un método estándar en ECMAScript 5.1
descargue el

1
¿Cómo puede el comentario anterior tener 4 votos a favor? Sí, Object.keyses un método estándar pero los objetos no tienen una propiedad de claves. Por lo tanto, este código informará que cualquier objeto está vacío, excepto que accidentalmente tiene una propiedad nombrada keycon un valor que nuevamente como una propiedad nombrada lengthque no es cero. ¡Horrible!
scravy

Object.keys(new Date()).length === 0; entonces esta respuesta puede ser engañosa.
cjbarth

11
@scravy Object es la clase Object. El objeto tiene un método estático llamado 'claves' que acepta un objeto como argumento. Este método devuelve una matriz de cadenas donde las cadenas son nombres de propiedad. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sgnl

35

Actuación

Hoy 2020.01.17 realizo pruebas en MacOs HighSierra 10.13.6 en Chrome v79.0, Safari v13.0.4 y Firefox v72.0, para las soluciones elegidas.

Conclusiones

  • soluciones basadas en for-in (A, J, L, M) son más rápidas
  • soluciones basadas en JSON.stringify (B, K) son lentas
  • Sorprendentemente, también la solución basada en Object(N) es lenta

ingrese la descripción de la imagen aquí

Detalles

A continuación en el fragmento se presentan 15 soluciones. Si desea ejecutar una prueba de rendimiento en su máquina, haga clic AQUÍ .

ingrese la descripción de la imagen aquí


Mucho de esto no tiene sentido porque estás basando todo en un retorno de falso o verdadero. A veces, la programación necesita una declaración if o un operador ternario. solo para tu información
Christian Matthew

1
Es la mejor respuesta, gracias, la primera solución funciona a las mil maravillas
Carlos Jesús Arancibia Taborga

33

¡Usar Object.keys (obj) .length (como se sugirió anteriormente para ECMA 5+) es 10 veces más lento para objetos vacíos! mantener con la vieja escuela (para ... en) opción.

Probado en Node, Chrome, Firefox e IE 9, se hace evidente que para la mayoría de los casos de uso:

  • (para ... en ...) es la opción más rápida de usar!
  • Object.keys (obj) .length es 10 veces más lento para objetos vacíos
  • JSON.stringify (obj) .length es siempre la más lenta (no es sorprendente)
  • Object.getOwnPropertyNames (obj) .length tarda más que Object.keys (obj) .length puede ser mucho más largo en algunos sistemas.

En términos de rendimiento, use:

function isEmpty(obj) { 
   for (var x in obj) { return false; }
   return true;
}

o

function isEmpty(obj) {
   for (var x in obj) { if (obj.hasOwnProperty(x))  return false; }
   return true;
}

Vea los resultados detallados de las pruebas y el código de prueba en ¿Está el objeto vacío?


Object.keyses lento, pero menos código En una página pequeña, donde esto se llama ... tal vez 10 veces ... ¿Será esto aún más lento teniendo en cuenta el tiempo de análisis adicional del código adicional?
Yankee

32

Puede verificar el recuento de las teclas de objeto:

if (Object.keys(a).length > 0) {
    // not empty
}

8
¿Por qué agregaría un comentario para una respuesta que ya se dio y daría una respuesta peor? stackoverflow.com/a/32108184/4229159 y es la primera respuesta de abril
Alejandro Vales

¿Qué sucede si tengo un objeto muy grande y hago eso en cada ciclo solo para ver si el objeto estaba vacío?
StefansArya

27
  1. Solo una solución alternativa. ¿Puede su servidor generar alguna propiedad especial en caso de que no haya datos?

    Por ejemplo:

    var a = {empty:true};

    Luego puede verificarlo fácilmente en su código de devolución de llamada AJAX.

  2. Otra forma de verificarlo:

    if (a.toSource() === "({})")  // then 'a' is empty

EDITAR : si usa cualquier biblioteca JSON (fe JSON.js), entonces puede probar la función JSON.encode () y probar el resultado con una cadena de valor vacía.


66
toSource()no es estándar y no funciona en IE u Opera (y potencialmente otros navegadores no me registro)
Christoph

44
@Thevs: quizás tenga una copia diferente de la versión actual de ECMA-262, pero la mía no incluye una toSourcepropiedad en la sección 15.2.4; según MDC, se introdujo en JS1.3 (es decir, Netscape Navigator 4.06), ¡pero NO está en ECMA-262, tercera edición!
Christoph

44
@Thevs: bueno, al menos 2 proveedores importantes de navegadores no lo implementaron, por lo que no es un estándar de facto, y como no está en ECMA-262, tampoco es real ...
Christoph

44
Incluso cuando funciona, toSource()es una forma horrible de hacer esto (como está JSON.encode()). Necesita construir una cadena que represente todo su objeto para verificar si está vacía. Existe la sobrecarga de convertir cosas en cadenas, pero además necesitará convertir un millón de cosas si su objeto tiene un millón de propiedades, mientras que solo mirar una le hará saber que no está vacío.
Jasper

44
@Thevs la sobrecarga es mayor, incluso si pudiera ser (no estoy seguro de que sea bajo todas las circunstancias) en el mismo orden de magnitud. Sin embargo, esa respuesta implica devolver falso tan pronto como se encuentre una propiedad diferente, lo que hace que la historia sea completamente diferente ...
Jasper

25

He creado una función completa para determinar si el objeto está vacío.

Utiliza Object.keysde ECMAScript 5 (ES5) funcionalidad si es posible para lograr el mejor rendimiento (ver tabla de compatibilidad ) y retrocesos con el enfoque más compatible para los motores más antiguos (navegadores).

Solución

/**
 * Returns true if specified object has no properties,
 * false otherwise.
 *
 * @param {object} object
 * @returns {boolean}
 */
function isObjectEmpty(object)
{
    if ('object' !== typeof object) {
        throw new Error('Object must be specified.');
    }

    if (null === object) {
        return true;
    }

    if ('undefined' !== Object.keys) {
        // Using ECMAScript 5 feature.
        return (0 === Object.keys(object).length);
    } else {
        // Using legacy compatibility mode.
        for (var key in object) {
            if (object.hasOwnProperty(key)) {
                return false;
            }
        }
        return true;
    }
}

Aquí está la esencia de este código.

Y aquí está el JSFiddle con demostración y una prueba simple.

Espero que ayude a alguien. ¡Salud!


3
Esto falla para un nullobjeto.

Hola @torazaburo! Gracias por tomar nota! He actualizado todas las fuentes con la implementación correcta.
Slava Fomin II

1
La longitud de Object.keys ({}). Es 10 veces más lenta que la opción (para ... en ...). Sugiero evitarla como una forma de comprobar si un objeto está vacío.
davidhadas

1
Object.keys(new Date()).length === 0; entonces esta respuesta puede ser engañosa.
cjbarth

19

Estoy usando esto

function isObjectEmpty(object) {
  var isEmpty = true;
  for (keys in object) {
     isEmpty = false;
     break; // exiting since we found that the object is not empty
  }
  return isEmpty;
}

P.ej:

var myObject = {}; // Object is empty
var isEmpty  = isObjectEmpty(myObject); // will return true;

// populating the object
myObject = {"name":"John Smith","Address":"Kochi, Kerala"}; 

// check if the object is empty
isEmpty  = isObjectEmpty(myObject); // will return false;

de aquí

Actualizar

O

puede usar la implementación jQuery de isEmptyObject

function isEmptyObject(obj) {
  var name;
  for (name in obj) {
    return false;
  }
  return true;
}

Hola. cuando prueba esta función con número o booleano verdadero o falso devuelve verdadero y este no es el resultado correcto. isObjectEmpty (verdadero). isObjectEmpty (falso). isObjectEmpty (1)
iman

2
Estamos comprobando si el objeto está vacío, no si el tipo de datos es un objeto. En su caso para verificar si es un objeto, necesitamos algo como if (typeof a === "object") {...}
kiranvj

15

El siguiente ejemplo muestra cómo probar si un objeto JavaScript está vacío, si por vacío queremos decir que no tiene propiedades propias.

El script funciona en ES6.

const isEmpty = (obj) => {
    if (obj === null ||
        obj === undefined ||
        Array.isArray(obj) ||
        typeof obj !== 'object'
    ) {
        return true;
    }
    return Object.getOwnPropertyNames(obj).length === 0;
};
console.clear();
console.log('-----');
console.log(isEmpty(''));           // true
console.log(isEmpty(33));           // true
console.log(isEmpty([]));           // true
console.log(isEmpty({}));           // true
console.log(isEmpty({ length: 0, custom_property: [] })); // false
console.log('-----');
console.log(isEmpty('Hello'));      // true
console.log(isEmpty([1, 2, 3]));    // true
console.log(isEmpty({ test: 1 }));  // false
console.log(isEmpty({ length: 3, custom_property: [1, 2, 3] })); // false
console.log('-----');
console.log(isEmpty(new Date()));   // true
console.log(isEmpty(Infinity));     // true
console.log(isEmpty(null));         // true
console.log(isEmpty(undefined));    // true


15

Según la especificación ES2017 en Object.entries () , la verificación es simple usando cualquier navegador moderno:

Object.entries({}).length === 0

3
¿Hay algún beneficio al usar esto en exceso Object.keyso Object.values?
faintsignal

@faintsignal usando esos están perfectamente bien. Acabo de agregar entradas ya que no lo encontré en los comentarios.
Vikrant

13
function isEmpty(obj) {
  for(var i in obj) { return false; }
  return true;
}

44
Eso también informará que es cierto cuando, por ejemplo, una biblioteca de JavaScript se extiende Objectcon un método a través de la cadena de prototipos, porque eso es enumerable y la for indeclaración recorre las propiedades enumerables.
viam0Zah


12

Me gustaría comprobar si tiene al menos una clave. Eso sería suficiente para decirme que no está vacío.

typeof obj !== "undefined" && Boolean(Object.keys(obj)[0])

1
¿Qué pasa si la primera clave devuelve falsevalor? El resultado será falseincorrecto.
Jimmy Obonyo Abor

He probado para eso. ¿Puedes dar un ejemplo de trabajo?
Tudor Morar

1
esto es breve y conciso, pero dará como resultado un error de tiempo de ejecución si el Objeto no está definido
Mrinmoy

11

Debajo del capó, todos los métodos de verificación vacíos en todas las bibliotecas usan claves de objeto para verificar la lógica. Es una forma extraña de hacer que sea comprensible, lo que puede poner en un método, descrito aquí .

for(key in obj){
   //your work here.
 break;
}

Que ha evolucionado en ES5 , ahora simplemente puede verificar la longitud de las claves del objeto, utilizando el Object.Keysmétodo que toma su objeto como parámetro:

if(Object.keys(obj).length > 0){
 //do your work here
}

O si está utilizando Lodash (debe ser) entonces.

 _.isEmpty(obj) //==true or false

Si bien es correcto como una forma extraña de hacer una declaración if, probablemente confundirá a alguien que mantendrá el código después de usted.
Soren

10


puede usar este código simple que no usó jQuery u otras bibliotecas

var a=({});

//check is an empty object
if(JSON.stringify(a)=='{}') {
    alert('it is empty');
} else {
    alert('it is not empty');
}

La clase JSON y sus funciones ( analizar y stringify ) son muy útiles, pero tiene algunos problemas con IE7 que puede solucionar con este código simple http://www.json.org/js.html .

Otra forma simple (forma más simple):
puede usar esta forma sin usar jQuery o el objeto JSON .

var a=({});

function isEmptyObject(obj) {
    if(typeof obj!='object') {
        //it is not object, so is not empty
        return false;
    } else {
        var x,i=0;
        for(x in obj) {
            i++;
        }
        if(i>0) {
            //this object has some properties or methods
            return false;
        } else {
            //this object has not any property or method
            return true;
        }
    }
}

alert(isEmptyObject(a));    //true is alerted

JSON.stringifyla solución falla si el objeto contiene propiedades que no se pueden clasificar en cadena, como funciones o "indefinido", aunque es un caso marginal.

10

La mejor manera que encontré:

function isEmpty(obj)
{
    if (!obj)
    {
        return true;
    }

    if (!(typeof(obj) === 'number') && !Object.keys(obj).length)
    {
        return true;
    }

    return false;
}

Trabaja para:

    t1: {} -> true
    t2: {0:1} -: false
    t3: [] -> true
    t4: [2] -> false
    t5: null -> true
    t6: undefined -> true
    t7: "" -> true
    t8: "a" -> false
    t9: 0 -> true
    t10: 1 -> false

3
Yo diría que 0 no está vacío ya que en realidad es un número. todo lo demás se ve bien, pero la solución es fácil. en la primera declaración if, agregue esto. if (!obj && obj !== 0).
mjwrazor

9

Mi toma:

function isEmpty(obj) {
    return !Object.keys(obj).length > 0;
}

var a = {a:1, b:2}
var b = {}

console.log(isEmpty(a)); // false
console.log(isEmpty(b)); // true

Simplemente, no creo que todos los navegadores se implementen Object.keys()actualmente.


2
Object.keys(new Date()).length === 0; entonces esta respuesta puede ser engañosa.
cjbarth

3
Depende si considera que una fecha siempre está "llena" a pesar de no exponer nunca las claves. Pero estoy de acuerdo en que si ese es su plan, agregar una instancia adicional de verificación para el constructor de fecha es una buena opción.
NiKo


7

¡Consideración! Cuidado con las limitaciones de JSON.

javascript:
  obj={  f:function(){}  };
  alert( "Beware!! obj is NOT empty!\n\nobj = {  f:function(){}  }" + 
               "\n\nJSON.stringify( obj )\n\nreturns\n\n" +
                        JSON.stringify( obj ) );

muestra

    ¡¡Tener cuidado!! ¡obj NO está vacío!

    obj = {f: función () {}}

    JSON.stringify (obj)

    devoluciones

    {}

7

La respuesta correcta es:

const isEmptyObject = obj =>
  Object.getOwnPropertyNames(obj).length === 0 &&
  Object.getOwnPropertySymbols(obj).length === 0 &&
  Object.getPrototypeOf(obj) === Object.prototype;

Esto verifica que:

  • El objeto no tiene propiedades propias (independientemente de la enumeración).
  • El objeto no tiene símbolos de propiedad propios.
  • El prototipo del objeto es exactamente Object.prototype.

En otras palabras, el objeto es indistinguible de uno creado con {}.


6

Además de la respuesta de Thevs:

var o = {};
alert($.toJSON(o)=='{}'); // true

var o = {a:1};
alert($.toJSON(o)=='{}'); // false

es jquery + jquery.json


No me gusta usar JSON porque no puede funcionar con estructuras de objetos circulares.
itdoesntwork

2
Si su página carga jQuery, úsela $.isEmptyObject(), no desperdicie ciclos con conversiones no obvias.
skierpage

6

Sugar.JS proporciona objetos extendidos para este propósito. El código es limpio y simple:

Hacer un objeto extendido:

a = Object.extended({})

Comprueba su tamaño:

a.size()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.