¿Cómo puedo comprobar si un objeto tiene una propiedad específica en JavaScript?
¿Cómo puedo comprobar si un objeto tiene una propiedad específica en JavaScript?
Considera:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
¿Hay otra manera de hacerlo?
Respuesta #1
ACTUALIZACIÓN 2022
Object.hasOwn()
Object.hasOwn()se recomienda sobreObject.hasOwnProperty()porque funciona para objetos creados usandoObject.create(null)y con objetos que han sobrescrito el método heredadohasOwnProperty(). Aunque es posible solucionar estos problemas llamando aObject.prototype.hasOwnProperty()en un objeto externo,Object.hasOwn()es más intuitivo.
Ejemplo
const object1 = {
prop: 'exists'
};
console.log(Object.hasOwn(object1, 'prop'));
// expected output: true
Respuesta original
Estoy realmente confundido por las respuestas que se han dado; la mayoría de ellas son simplemente incorrectas. Por supuesto, puedes tener propiedades de un objeto que tengan valores undefined, null o false. Así que simplemente reducir la comprobación de la propiedad a typeof this[property] o, aún peor, x.key te dará resultados completamente engañosos.
Depende de lo que estés buscando. Si quieres saber si un objeto contiene físicamente una propiedad (y no proviene de algún lugar en la cadena de prototipos), entonces object.hasOwnProperty es el camino a seguir. Todos los navegadores modernos lo soportan. (Faltaba en versiones antiguas de Safari - 2.0.1 y anteriores - pero esas versiones del navegador casi ya no se usan.)
Si lo que estás buscando es si un objeto tiene una propiedad que sea iterable (cuando iteras sobre las propiedades del objeto, aparecerá) entonces hacer: prop in object te dará el efecto deseado.
Dado que usar hasOwnProperty es probablemente lo que deseas, y considerando que puede que quieras un método alternativo, te presento la siguiente solución:
var obj = {
a: undefined,
b: null,
c: false
};
// a, b, c all found
for ( var prop in obj ) {
document.writeln( "Object1: " + prop );
}
function Class(){
this.a = undefined;
this.b = null;
this.c = false;
}
Class.prototype = {
a: undefined,
b: true,
c: true,
d: true,
e: true
};
var obj2 = new Class();
// a, b, c, d, e found
for ( var prop in obj2 ) {
document.writeln( "Object2: " + prop );
}
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
if ( Object.prototype.hasOwnProperty ) {
var hasOwnProperty = function(obj, prop) {
return obj.hasOwnProperty(prop);
}
}
// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
if ( hasOwnProperty(obj2, prop) ) {
document.writeln( "Object2 w/ hasOwn: " + prop );
}
}
Lo anterior es una solución funcional y compatible con varios navegadores para hasOwnProperty(), con una salvedad: no puede distinguir entre los casos en los que una propiedad idéntica está en el prototipo y en la instancia; simplemente asume que proviene del prototipo. Podrías ajustarla para que sea más permisiva o estricta, según tu situación, pero al menos esto debería ser más útil.
Respuesta #2
Con Underscore.js o (aún mejor) Lodash:
_.has(x, 'key');
Que llama a Object.prototype.hasOwnProperty, pero (a) es más corto de escribir, y (b) usa "una referencia segura a hasOwnProperty" (es decir, funciona incluso si hasOwnProperty es sobrescrito).
En particular, Lodash define _.has como:
function has(object, key) {
return object ? hasOwnProperty.call(object, key) : false;
}
// hasOwnProperty = Object.prototype.hasOwnProperty
Actualización 2023
Como se señaló en la respuesta de John Resig, esto ahora está esencialmente incorporado con Object.hasOwn. Lodash/underscore siguen siendo alternativas para los casos en los que Object.hasOwn no está disponible.
Respuesta #3
Puedes usar esto (pero lee la advertencia a continuación):
var x = {
'key': 1
};
if ('key' in x) {
console.log('has');
}Pero ten cuidado: 'constructor' in x devolverá true incluso si x es un objeto vacío, lo mismo ocurre con 'toString' in x y muchos otros. Es mejor usar Object.hasOwn(x, 'key').
Respuesta #4
Nota: lo siguiente hoy en día es en gran medida obsoleto gracias al modo estricto y a hasOwnProperty. La solución correcta es usar el modo estricto y verificar la presencia de una propiedad usando obj.hasOwnProperty. Esta respuesta precede a ambas cosas, al menos tal como se implementan ampliamente (sí, es así de antigua). Tómelo como una nota histórica.
Ten en cuenta que undefined (desafortunadamente) no es una palabra reservada en JavaScript si no estás usando el modo estricto. Por lo tanto, alguien (alguien más, obviamente) podría tener la gran idea de redefinirlo, rompiendo tu código.
Por lo tanto, un método más robusto es el siguiente:
if (typeof(x.attribute) !== 'undefined')
Por otro lado, este método es mucho más verboso y también más lento. :-/
Una alternativa común es asegurarse de que undefined esté realmente indefinido, por ejemplo, colocando el código en una función que acepte un parámetro adicional, llamado undefined, al que no se le pase un valor. Para asegurarse de que no se le pase un valor, podrías simplemente llamarla tú mismo de inmediato, por ejemplo:
(function (undefined) {
… your code …
if (x.attribute !== undefined)
… mode code …
})();
Respuesta #5
if (x.key !== undefined)
Parece que Armin Ronacher ya me ganó la partida, pero:
Object.prototype.hasOwnProperty = function(property) {
return this[property] !== undefined;
};
x = {'key': 1};
if (x.hasOwnProperty('key')) {
alert('have key!');
}
if (!x.hasOwnProperty('bar')) {
alert('no bar!');
}
Una solución más segura, pero más lenta, como señalaron Konrad Rudolph y Armin Ronacher, sería:
Object.prototype.hasOwnProperty = function(property) {
return typeof this[property] !== 'undefined';
};
Respuesta #6
Considerando el siguiente objeto en Javascript
const x = {key: 1};
Puedes usar el operador in para verificar si la propiedad existe en un objeto:
console.log("key" in x);
También puedes recorrer todas las propiedades del objeto usando un bucle for - in, y luego verificar la propiedad específica:
for (const prop in x) {
if (prop === "key") {
//Do something
}
}
Debes considerar si esta propiedad del objeto es enumerable o no, porque las propiedades no enumerables no aparecerán en un bucle for-in. Además, si la propiedad enumerable está ocultando una propiedad no enumerable del prototipo, no aparecerá en Internet Explorer 8 y versiones anteriores.
Si deseas una lista de todas las propiedades de instancia, ya sean enumerables o no, puedes usar
Object.getOwnPropertyNames(x);
Esto devolverá un arreglo de nombres de todas las propiedades que existen en un objeto.
Las reflexiones proporcionan métodos que se pueden usar para interactuar con objetos de Javascript. El método estático Reflect.has() funciona como el operador in, pero como una función.
console.log(Reflect.has(x, 'key'));
// expected output: true
console.log(Reflect.has(x, 'key2'));
// expected output: false
console.log(Reflect.has(object1, 'toString'));
// expected output: true
Finalmente, puedes usar el operador typeof para verificar directamente el tipo de dato de la propiedad del objeto:
if (typeof x.key === "undefined") {
console.log("undefined");
}
Si la propiedad no existe en el objeto, devolverá la cadena undefined. De lo contrario, devolverá el tipo de propiedad correspondiente. Sin embargo, tenga en cuenta que esto no siempre es una forma válida de verificar si un objeto tiene una propiedad o no, porque podría tener una propiedad que esté establecida como undefined, en cuyo caso, usar typeof x.key aún devolvería true (aunque la clave todavía esté en el objeto).
De manera similar, puedes comprobar si una propiedad existe comparándola directamente con la propiedad undefined de Javascript
if (x.key === undefined) {
console.log("undefined");
}
Esto debería funcionar a menos que la clave se haya establecido específicamente en undefined en el objeto x
Respuesta #7
Vamos a cortar un poco de confusión aquí. Primero, vamos a simplificar asumiendo que hasOwnProperty ya existe; esto es cierto en la gran mayoría de los navegadores actuales en uso.
hasOwnProperty devuelve true si el nombre del atributo que se le pasa ha sido agregado al objeto. Es completamente independiente del valor real asignado a él, que puede ser exactamente undefined.
Por lo tanto:
var o = {}
o.x = undefined
var a = o.hasOwnProperty('x') // a is true
var b = o.x === undefined // b is also true
Sin embargo:
var o = {}
var a = o.hasOwnProperty('x') // a is now false
var b = o.x === undefined // b is still true
El problema es qué ocurre cuando un objeto en la cadena de prototipos tiene un atributo con el valor de undefined. hasOwnProperty será falso para él, y también lo será !== undefined. Sin embargo, for..in todavía lo listará en la enumeración.
En resumen, no existe una forma compatible entre navegadores (ya que Internet Explorer no expone __prototype__) de determinar que un identificador específico no se ha adjuntado a un objeto ni a nada en su cadena de prototipos.
Respuesta #8
Si estás buscando una propiedad, entonces "no". Quieres:
if ('prop' in obj) { }
En general, no deberías preocuparte de si la propiedad proviene del prototipo o del objeto.
Sin embargo, debido a que usaste 'key' en tu código de ejemplo, parece que estás tratando el objeto como un hash, en cuyo caso tu respuesta tendría sentido. Todas las claves del hash serían propiedades en el objeto, y evitas las propiedades adicionales que contribuye el prototipo.
La respuesta de John Resig fue muy completa, pero pensé que no estaba clara. Especialmente sobre cuándo usar "'prop' in obj".
Respuesta #9
Para probar objetos simples, use:
if (obj[x] !== undefined)
Si no sabes qué tipo de objeto es, usa:
if (obj.hasOwnProperty(x))
Todas las demás opciones son más lentas...
Detalles
Una evaluación de rendimiento de 100,000,000 ciclos bajo Node.js para las cinco opciones sugeridas por otros aquí:
function hasKey1(k,o) { return (x in obj); }
function hasKey2(k,o) { return (obj[x]); }
function hasKey3(k,o) { return (obj[x] !== undefined); }
function hasKey4(k,o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k,o) { return (obj.hasOwnProperty(x)); }
La evaluación nos dice que a menos que queramos comprobar específicamente la cadena de prototipos del objeto así como el propio objeto, no deberíamos usar la forma común:
if (X in Obj)...
Es entre 2 y 6 veces más lento dependiendo del caso de uso
hasKey1 execution time: 4.51 s
hasKey2 execution time: 0.90 s
hasKey3 execution time: 0.76 s
hasKey4 execution time: 0.93 s
hasKey5 execution time: 2.15 s
En resumen, si tu Obj no es necesariamente un objeto simple y deseas evitar verificar la cadena de prototipos del objeto y asegurarte de que x sea propiedad directa de Obj, usa if (obj.hasOwnProperty(x))....
De lo contrario, al usar un objeto sencillo y no preocuparse por la cadena de prototipos del objeto, usar if (typeof(obj[x]) !== 'undefined')... es la forma más segura y rápida.
Si usas un objeto simple como una tabla hash y nunca haces nada raro, yo usaría if (obj[x])... ya que lo encuentro mucho más legible.
Respuesta #10
Sí, lo es :) Creo que también puedes hacer Object.prototype.hasOwnProperty.call(x, 'key'), lo cual también debería funcionar si x tiene una propiedad llamada hasOwnProperty :)
Pero eso verifica las propiedades propias. Si quieres comprobar si tiene una propiedad que también puede ser heredada, puedes usar typeof x.foo != 'undefined'.
Respuesta #11
if(x.hasOwnProperty("key")){
// …
}
porque
if(x.key){
// …
}
falla si x.key es falso (por ejemplo, x.key === "").
Respuesta #12
También puedes usar el objeto Reflect de ES6:
x = {'key': 1};
Reflect.has( x, 'key'); // returns true
La documentación en MDN para Reflect.has se puede encontrar aquí.
El método estático
Reflect.has()funciona como el operador in, pero en forma de función.
Respuesta #13
No hagas esto object.hasOwnProperty(key)). Es realmente malo porque estos métodos pueden ser ocultados por propiedades en el objeto en cuestión - considera { hasOwnProperty: false } - o, el objeto puede ser un objeto nulo (Object.create(null)).
La mejor manera es hacer Object.prototype.hasOwnProperty.call(object, key) o:
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(object, key));
/* Or */
import has from 'has'; // https://www.npmjs.com/package/has
console.log(has(object, key));
Respuesta #14
OK, parece que tenía la respuesta correcta a menos que no quieras propiedades heredadas:
if (x.hasOwnProperty('key'))
Aquí hay algunas otras opciones para incluir propiedades heredadas:
if (x.key) // Quick and dirty, but it does the same thing as below.
if (x.key !== undefined)
Respuesta #15
Otra forma relativamente simple es usar Object.keys. Esto devuelve un array, lo que significa que obtienes todas las características de un array.
var noInfo = {};
var info = {something: 'data'};
Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true
Aunque estamos en un mundo con gran soporte de navegadores. Debido a que esta pregunta es tan antigua, pensé en agregar esto: Esto es seguro de usar a partir de JavaScript v1.8.5.
Respuesta #16
JavaScript ahora está evolucionando y creciendo ya que ahora tiene formas buenas e incluso eficientes de verificarlo.
Aquí hay algunas formas fáciles de comprobar si un objeto tiene una propiedad en particular:
- Usando
hasOwnProperty()
const hero = {
name: 'Batman'
};
hero.hasOwnProperty('name'); // => true
hero.hasOwnProperty('realName'); // => false
- Usando la palabra clave/operador
in
const hero = {
name: 'Batman'
};
'name' in hero; // => true
'realName' in hero; // => false
- Comparando con la palabra clave
undefined
const hero = {
name: 'Batman'
};
hero.name; // => 'Batman'
hero.realName; // => undefined
// So consider this
hero.realName == undefined // => true (which means property does not exists in object)
hero.name == undefined // => false (which means that property exists in object)
Para más información, consulte aquí.
