¿Cómo verificar si el objeto tiene alguna propiedad en JavaScript?

168

Asumiendo que declaro

var ad = {}; 

¿Cómo puedo verificar si este objeto contendrá propiedades definidas por el usuario?

Ricky
fuente

Respuestas:

86

Puede recorrer las propiedades de su objeto de la siguiente manera:

for(var prop in ad) {
    if (ad.hasOwnProperty(prop)) {
        // handle prop as required
    }
}

Es importante utilizar el hasOwnProperty()método para determinar si el objeto tiene la propiedad especificada como una propiedad directa y no se hereda de la cadena de prototipos del objeto.

Editar

De los comentarios: puede poner ese código en una función y hacer que devuelva falso tan pronto como llegue a la parte donde está el comentario

Prueba de rendimiento

Prueba de Object.Keys vs For..In Al probar cualquier propiedad

Daniel Vassallo
fuente
2
Hola Daniel, en realidad estoy buscando un dispositivo para verificar si un objeto contiene propiedades definidas por el usuario o no. No verificar si existe una propiedad específica.
Ricky
77
@Ricky: puede poner ese código en una función y hacer que devuelva falso tan pronto como llegue a la parte donde está el comentario.
Daniel Vassallo
8
Creo que estos días usar Object.keyssería lo más fácil: var a = [1,2,3];a.something=4;console.log(Object.keys(a))debido a que ya es parte de ECMA 5, puede calzarlo con seguridad: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
HMR
2
Tenga en cuenta que "en estos días" con ES5, los objetos nativos pueden tener propiedades propias no enumerables, por ejemplo Object.defineProperty(obj, 'foo', {enumerable:false, value:'foo'}).
RobG
2
Esta solución es una forma de verificar las claves que existen , pero la respuesta verdadera, eficiente y más correcta se encuentra a continuación utilizando Object.keys (x) .length. No necesita hacer su propia función, ¡ya existe una!
dudewad
197

Puede usar el Object.keysmétodo incorporado para obtener una lista de claves en un objeto y probar su longitud.

var x = {};
// some code where value of x changes and than you want to check whether it is null or some object with values

if(Object.keys(x).length > 0){
 // Your code here if x has some properties  
}
Dhaval Chaudhary
fuente
14
Esta de aquí es la respuesta correcta. La respuesta aceptada arriba es una solución alternativa y es más costosa que simplemente verificar la cantidad de claves; Esto tiene mucho más sentido .
dudewad
66
Object.keys ("mystring"); produce claves también, lo que creo que es indeseable. Esta respuesta es incompleta en mi opinión.
Mike de Klerk
2
@MikedeKlerk por favor léalo cuidadosamente, no es Object.keys ("mystring"); es Object.keys (objectVariableName) que devolverá la matriz de todas las claves del objeto. ej .: {'x': 'abc', 'y': 'def'} será ['x', 'y']
Dhaval Chaudhary el
3
@DhavalChaudhary Gracias por su respuesta a mi comentario. Cuando pruebo este código var str = "MyString"; Object.keys(str);, la consola emite 8 teclas, de 0 a 7, para cada personaje. ¿O todavía no entiendo la respuesta?
Mike de Klerk
66
@MikedeKlerk, pero es la única solución para los objetos, no para las cadenas, por favor consulte la pregunta.
Dhaval Chaudhary
111

¿Qué hay de hacer una función simple?

function isEmptyObject(obj) {
  for(var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
  }
  return true;
}

isEmptyObject({}); // true
isEmptyObject({foo:'bar'});  // false

La hasOwnPropertyllamada al método directamente en el Object.prototypees solo para agregar un poco más de seguridad , imagine lo siguiente usando una obj.hasOwnProperty(...)llamada normal :

isEmptyObject({hasOwnProperty:'boom'});  // false

Nota: (para el futuro) El método anterior se basa en la for...indeclaración, y esta declaración solo itera sobre las propiedades enumerables , en el Estándar ECMAScript implementado actualmente más ampliamente (3a edición) el programador no tiene ninguna forma de crear propiedades no enumerables .

Sin embargo, esto ha cambiado ahora con ECMAScript 5th Edition , y podemos crear propiedades no enumerables, no editables o no eliminables, por lo que el método anterior puede fallar , por ejemplo:

var obj = {};
Object.defineProperty(obj, 'test', { value: 'testVal', 
  enumerable: false,
  writable: true,
  configurable: true
});
isEmptyObject(obj); // true, wrong!!
obj.hasOwnProperty('test'); // true, the property exist!!

Una solución ECMAScript 5 a este problema sería:

function isEmptyObject(obj) {
  return Object.getOwnPropertyNames(obj).length === 0;
}

El Object.getOwnPropertyNamesmétodo devuelve un que Arraycontiene los nombres de todas las propiedades propias de un objeto, enumerable o no , este método está siendo implementado ahora por proveedores de navegadores, ya está en Chrome 5 Beta y las últimas versiones nocturnas de WebKit.

Object.defineProperty también está disponible en esos navegadores y en las últimas versiones de Firefox 3.7 Alpha.

CMS
fuente
1
¿Cuál es la ventaja de Object.prototype.hasOwnProperty.call (obj, prop) sobre obj.hasOwnProperty (prop)?
Casey Chu
3
@Casey, editado, si un objeto anula la hasOwnPropertypropiedad, la función podría fallar ... Sé que soy un poco paranoico ... pero a veces no sabes en qué tipo de entorno se usará tu código, pero sabes qué método quieres usar ...
CMS
2
¡+1 por responder esta pregunta ... y otras preguntas del futuro! :)
Daniel Vassallo
1
Tenga en cuenta que también hay un error en IE en el que si tiene una propiedad con un nombre que coincide con una propiedad no enumerable Object.prototype, no se enumera por for...in. Entonces isEmptyObject({toString:1})fallará. Esta es una de las razones desafortunadas que no puedes bastante utilizar Objectcomo una asignación de propósito general.
bobince
1
@ MichaelMartin-Smucker: las claves solo devuelven propiedades propias enumerables, por lo que no es adecuado aquí.
RobG
58

Con jQuery puedes usar:

$.isEmptyObject(obj); // Returns: Boolean

A partir de jQuery 1.4, este método verifica tanto las propiedades del objeto como las propiedades heredadas de los prototipos (ya que no utiliza hasOwnProperty).

Con ECMAScript 5th Edition en navegadores modernos (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) puede usar el método incorporado Object.keys :

var obj = { blah: 1 };
var isEmpty = !Object.keys(obj).length;

O simplemente JavaScript antiguo:

var isEmpty = function(obj) {
               for(var p in obj){
                  return false;
               }
               return true;
            };
kayz1
fuente
13

Si está utilizando underscore.js, puede usar la función _.isEmpty :

var obj = {};
var emptyObject = _.isEmpty(obj);
Conejito Gruff
fuente
1
Solo para cualquiera que pase, este no es un método dedicado a los objetos. _.isEmpty([]) // true Asegúrese de verificar primero: stackoverflow.com/a/22482737/1922747
djv
11

Si está dispuesto a usar lodash , puede usar el somemétodo.

_.some(obj) // returns true or false

Ver este pequeño ejemplo de jsbin

sfs
fuente
var x = [1,2] // verdadero
djv
@damionjn Agregué tu código al ejemplo. Veo su punto con la matriz que devuelve la respuesta incorrecta, pero OP inicialmente declaró una variable como un objeto, así que creo que está bien asumir esto. Hay una respuesta anterior que utiliza el método isEmpty de guiones bajos (lodash tiene el mismo método). Esa respuesta tiene exactamente el mismo problema. Si le da a isEmpty una matriz no vacía, también obtendrá el resultado incorrecto.
sfs el
Es justo, pero deberíamos proporcionar respuestas con todas las bases cubiertas para estar seguros de las mejores prácticas. Tienes razón, pasé por su respuesta sin ninguna crítica. Solo para cualquiera que pase, este no es un método dedicado a los objetos. _.some([1, 2]) // true Asegúrese de verificar primero: stackoverflow.com/a/13356338/1922747
djv el
5
for (var hasProperties in ad) break;
if (hasProperties)
    ... // ad has properties

Si tiene que estar seguro y buscar prototipos de objetos (algunas bibliotecas los agregan y no están allí de forma predeterminada):

var hasProperties = false;
for (var x in ad) {
    if (ad.hasOwnProperty(x)) {
        hasProperties = true;
        break;
    }
}
if (hasProperties)
    ... // ad has properties
Casey Chu
fuente
1
en su solución no hay filtrado para las propiedades de prototipo no deseadas, lo que significa que podría comportarse mal cuando se usa una biblioteca como Prototype.js o un usuario sin experiencia agregó propiedades de prototipo adicionales al objeto. Echa un vistazo a la solución de Daniels en esta página.
Joscha
No tiene que usar una biblioteca o no tener experiencia para extender el prototipo de un objeto. Algunos programadores experimentados hacen esto todo el tiempo.
Alsciende
2
for(var memberName in ad)
{
  //Member Name: memberName
  //Member Value: ad[memberName]
}

Miembro significa propiedad de miembro, variable de miembro, como quiera llamarlo> _>

El código anterior devolverá TODO, incluido toString ... Si solo desea ver si el prototipo del objeto se ha extendido:

var dummyObj = {};  
for(var memberName in ad)
{
  if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
  //Member Name: memberName
  //Member Value: ad[memberName]

}

Nota A: Verificamos si el miembro del objeto ficticio tiene el mismo tipo que el miembro de nuestro objeto de prueba. Si es una extensión, el tipo de miembro de dummyobject debe ser "indefinido"

Warty
fuente
Hola, ¿puedo saber si un objeto contiene propiedades o no? Gracias
Ricky
en su solución no hay filtrado para las propiedades de prototipo no deseadas, lo que significa que podría comportarse mal cuando se usa una biblioteca como Prototype.js o un usuario sin experiencia agregó propiedades de prototipo adicionales al objeto.
Joscha
echa un vistazo a la solución de Daniels en esta página: ¡es menos propenso a errores!
Joscha
2
Su primer bloque de código no lo cubre en absoluto. el segundo bloque de código se comporta mal si agrego una variable al objeto "ad" que no está definido. Realmente, mira la respuesta de Daniels, es la única correcta y rápida, ya que usa una implementación nativa llamada "hasOwnProperty".
Joscha
@Ricky: Si desea verificar si un objeto contiene propiedades, simplemente puede usar el ejemplo en mi respuesta: stackoverflow.com/questions/2673121/… . Si el código llega al comentario, su objeto no tendría ninguna propiedad directa. Si no, lo haría.
Daniel Vassallo
2
var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
// as of this line hasAnyProps will show Boolean whether or not any iterable props exist

Simple, funciona en todos los navegadores, y aunque técnicamente es un bucle para todas las teclas del objeto, NO recorre todas ellas ... o hay 0 y el bucle no se ejecuta o hay algunos y se rompe después del primer uno (porque todo lo que estamos comprobando es si hay CUALQUIER ... entonces, ¿por qué continuar?)

Jimbo Jonny
fuente
1

Respuesta muy tardía, pero así es como puedes manejarlo con prototipos.

Array.prototype.Any = function(func) {
    return this.some(func || function(x) { return x });
}

Object.prototype.IsAny = function() {
    return Object.keys(this).Any();
}
Lucro
fuente
0

Cuando esté seguro de que el objeto es definido por el usuario, la forma más fácil de determinar si UDO está vacío, sería el siguiente código:

isEmpty=
/*b.b Troy III p.a.e*/
function(x,p){for(p in x)return!1;return!0};

Aunque este método es (por naturaleza) deductivo, es el más rápido y más rápido posible.

a={};
isEmpty(a) >> true

a.b=1
isEmpty(a) >> false 

ps:! no lo use en objetos definidos por el navegador.

Bill el lagarto
fuente
... devuelve 0; volver 1}; seria lo mismo?
commonpike
1
@pike no, return! 1; return! 0 es lo mismo que return false; return true
Christophe
0

Respuesta tardía, pero algunos marcos manejan los objetos como enumerables. Por lo tanto, bob.js puede hacerlo así:

var objToTest = {};
var propertyCount = bob.collections.extend(objToTest).count();
Tengiz
fuente
0

Puedes usar lo siguiente:

Doble explosión búsqueda de propiedades

var a = !![]; // true
var a = !!null; // false

hasOwnProperty Esto es algo que solía usar:

var myObject = {
  name: 'John',
  address: null
};
if (myObject.hasOwnProperty('address')) { // true
  // do something if it exists.
}

Sin embargo, JavaScript decidió no proteger el nombre del método, por lo que podría ser alterado.

var myObject = {
  hasOwnProperty: 'I will populate it myself!'
};

utilería en myObject

var myObject = {
  name: 'John',
  address: null,
  developer: false
};
'developer' in myObject; // true, remember it's looking for exists, not value.

tipo de

if (typeof myObject.name !== 'undefined') {
  // do something
}

Sin embargo, no comprueba si es nulo.

Creo que esta es la mejor manera.

en operador

var myObject = {
  name: 'John',
  address: null
};

if('name' in myObject) {
  console.log("Name exists in myObject");
}else{
  console.log("Name does not exist in myObject");
}

resultado:

El nombre existe en myObject

Aquí hay un enlace que entra en más detalles sobre el operador in: Determinar si existe una propiedad de objeto

James Drinkard
fuente
0

Función ES6

/**
 * Returns true if an object is empty.
 * @param  {*} obj the object to test
 * @return {boolean} returns true if object is empty, otherwise returns false
 */
const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0

Ejemplos:


let obj = "this is an object with String constructor"
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {}
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = []
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = [{prop:"value"}]
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {prop:"value"}
console.log(pureObjectIsEmpty(obj)) // empty? false
Sébastien
fuente
-1

¿Qué tal esto?

var obj = {},
var isEmpty = !obj;
var hasContent = !!obj
Peter Toth
fuente
Esta respuesta no responde la pregunta. OP pregunta si un objeto contiene propiedades definidas por el usuario: su respuesta verifica si el objeto mismo se convertirá en un valor falso booleano.
Jasmonate
... y luego me di cuenta de que James ya incluía esta opción en su respuesta. Lo siento chicos.
Peter Toth