¿Cómo verifico si un objeto tiene una propiedad específica en JavaScript?

1626

¿Cómo verifico si un objeto tiene una propiedad específica en JavaScript?

Considerar:

x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
    //Do this
}

¿Es esa la mejor forma de hacerlo?

4
  • 27
    Escribí una prueba jsperf con las respuestas de todos para ver cuál es más rápido: jsperf.com/dictionary-contains-keystyfle 10/03/2016 a las 16:36
  • ('propertyName' en Objeto)? 'la propiedad está allí': 'la propiedad no está allí'Mohan Ram 5 oct 2018 a las 9:08
  • 1
    @styfle gracias por la prueba jsperf. iny hasOwnPropertysalió mucho más lento que los demás para mí (98% más lento). No me sorprende hasOwnPropertyser más lento, pero sí me sorprende in. evanrmurphy 16/11/18 a las 20:16
  • Hay una nueva propuesta de etapa 3 Object.hasOwn, que aborda algunos de los problemas de Object.prototype.hasOwnProperty. Sebastian Simon 19 de agosto a las 22:19
1507

Estoy realmente confundido por las respuestas que se han dado, la mayoría de ellas son completamente incorrectas. Por supuesto, puede tener propiedades de objeto que tengan valores indefinidos, nulos o falsos. Por lo tanto, simplemente reducir el cheque de propiedad typeof this[property]o, lo que es peor, x.keyle dará resultados completamente engañosos.

Depende de lo que estés buscando. Si desea saber si un objeto contiene físicamente una propiedad (y no proviene de algún lugar en la cadena del prototipo), este object.hasOwnPropertyes el camino a seguir. Todos los navegadores modernos lo admiten. (Faltaba en las versiones anteriores de Safari, 2.0.1 y anteriores, pero esas versiones del navegador rara vez se usan más).

Si lo que está buscando es si un objeto tiene una propiedad que es iterable (cuando itera sobre las propiedades del objeto, aparecerá), entonces hacer: prop in objectle dará el efecto deseado.

Dado que usar hasOwnPropertyes probablemente lo que desea, y considerando que es posible que desee un método alternativo, le 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 que funciona en varios navegadores, hasOwnPropertycon una salvedad: no puede distinguir entre los casos en los que hay una propiedad idéntica en el prototipo y en la instancia; simplemente asume que proviene del prototipo. Puede cambiarlo para que sea más indulgente o estricto, según su situación, pero al menos esto debería ser más útil.

9
  • 5
    @grantwparks Si está creando un complemento de control deslizante simple y desea verificar la existencia de un elemento de opciones, entonces esto podría ser más de lo necesario. Puedes hacer algo como var w = opts.w || 100;. Pero si se encuentra en una biblioteca, es posible que deba ir un poco más lejos en algunas partes. Halil Özgür 22/02/11 a las 16:28
  • 2
    @Kasztan __proto__no es estándar y no funciona en algunos navegadores más antiguos. E incluso con la reciente adición del Object.getPrototypeOfestándar dice que todavía no se puede cambiar el prototipo de un objeto existente. Matt Browne 25 feb 2013 a las 19:11
  • 1
    Las respuestas de John Resig no parecen funcionar en IE8, véalo fallar en esta demostración en vivo jsbin.com/tovaburefeva/1/edit?js,output . Creo que es porque hasOwnProperty() "is not supported on host objects for Internet Explorer 8 and below"vea msdn.microsoft.com/en-us/library/ie/328kyd6z(v=vs.94).aspx y también stackoverflow.com/questions/8157700/…Adrien Be 14/10/2014 a las 10:43
  • 14
    Un for(prop in object)bucle itera solo propiedades enumerables. Sin embargo, prop in objectcomprueba si objecttiene la propiedad propen algún lugar de la cadena prototípica, independientemente de si es enumerable o no. Oriol 5 de enero de 2016 a las 23:27
  • 1
    Advertencia: no utilice la incomprobación de primitivas. S.D. 2 sep.2020 a las 20:08
311

Con Underscore.js o ( incluso mejor ) Lodash :

_.has(x, 'key');

Lo que llama Object.prototype.hasOwnProperty, pero (a) es más corto de escribir, y (b) usa "una referencia segura a hasOwnProperty" (es decir, funciona incluso si hasOwnPropertyse sobrescribe).

En particular, Lodash define _.hascomo:

   function has(object, key) {
      return object ? hasOwnProperty.call(object, key) : false;
   }
   // hasOwnProperty = Object.prototype.hasOwnProperty
11
  • 63
    Supongo que es porque "agregar esta biblioteca" rara vez es una solución popular, incluso cuando la pregunta es sobre la manipulación compleja del DOM y la respuesta es "usa jQuery". Winfield Trail 4 de septiembre de 2014 a las 19:15
  • 12
    Veo tu punto, @sudowned, gracias. Por cierto, si uno fuera reacio a incluir toda la biblioteca lodash, podría compilar subcomponentes o npm install lodash.hasque exponga un módulo npm con solo una hasfunción que compila hasta 175 bytes cuando se minimiza. También es interesante mirar el lodash.has/index.jspara ver cómo funciona una biblioteca muy popular y confiable. Brian M. Hunt 4 de septiembre de 2014 a las 19:41
  • 9
    y lodashlas versiones funcionan con esto: .has(undefined, 'someKey') => falsewhile underscoredevuelveundefinedBrad Parks 10 de septiembre de 2014 a las 11:06
  • dieciséis
    Para todos los que se quejan de agregar lodashcomo "otra dependencia más": es una biblioteca bastante común (si no la más común) para este tipo de cosas. Diviértete reinventando la rueda. Priidu Neemre 18/11/2016 a las 12:37
  • 15
    Incluso si desea reinventar la rueda, comprobar las ruedas existentes no es una mala idea. AturSams 25/04/2017 a las 11:53
181

Usar:

var x = {
  'key': 1
};

if ('key' in x) {
  console.log('has');
}
4
  • dieciséis
    Solo para tener en cuenta, funciona con 'objetos' en sentido estricto, por lo que declarado como {} o creado usando el constructor, no acepta matrices ni primitivas. No es que el OP lo haya requerido, pero algunas otras respuestas presentan técnicas que son más amplias (trabajar con matrices, cadenas, etc.)Danubian Sailor 27 de agosto de 2014 a las 12:22
  • @ РСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ gracias por señalar eso (la respuesta aceptada no entra en detalles sobre por qué se debe usar el inoperador o no. También tenga en cuenta que el inoperador tiene una excelente compatibilidad con el navegador IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+ stackoverflow.com/questions/2920765/…Adrien Be 15/10/2014 a las 7:42
  • 3
    El operador intambién verifica las propiedades del prototipo, mientras que hasOwnPropertyitera solo las propiedades definidas por el usuario. Referencia: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…adi518 9/07/2016 a las 11:57
  • 3
    'key' in x hacer el trabajo con matrices. Prueba: stackoverflow.com/questions/33592385/…CosmoMyzrailGorynych 5 de enero de 2017 a las 1:54
138

Nota : lo siguiente es hoy en día en gran parte obsoleto gracias al modo estricto y hasOwnProperty. La solución correcta es usar el modo estricto y verificar la presencia de una propiedad usando obj.hasOwnProperty. Esta respuesta es anterior a ambas cosas, al menos tan ampliamente implementada (sí, es así de antigua). Tome lo siguiente como nota histórica.


Tenga en cuenta que undefined(desafortunadamente) no es una palabra reservada en JavaScript si no está usando el modo estricto. Por lo tanto, alguien (alguien más, obviamente) podría tener la gran idea de redefinirlo, rompiendo su código.

Por 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 detallado y también más lento. : - /

Una alternativa común es asegurarse de que en realidad no undefinedesté definido, por ejemplo, poniendo el código en una función que acepta un parámetro adicional, llamado , al que no se le pasa un valor. Para asegurarse de que no se le haya pasado un valor, puede llamarlo usted mismo inmediatamente, por ejemplo:undefined

(function (undefined) {
    … your code …
    if (x.attribute !== undefined)
        … mode code …
})();
8
  • 6
    Solo por curiosidad, ya que void 0está definido para devolver lo canónico undefined, ¿se podría hacer x.attribute !== void 0? Brian M. Hunt 1 feb 2013 a las 17:01
  • 1
    Brian: No soy un experto, pero seguro que parece una forma inteligente de hacerlo bien. Christopher Smith 25 feb 2013 a las 22:29
  • 40
    Si el famoso 'alguien más' ha redefinido lo que es indefinido, creo que el mejor curso de acción sería reescribir ESE código. Oskar Holmkratz 18 de mayo de 2013 a las 18:00
  • 3
    Lo mejor para tener una var indefinida sólida es trabajar dentro de un cierre y tener una firma de función inigualable:(function (undefined) { // undefined is actually undefined here })();bgusach 15/10/2013 a las 10:20
  • 1
    @evanrmurphy No use eso, está muy desactualizado (vea la nota al comienzo de mi respuesta). Konrad Rudolph 17/11/18 a las 13:19
57
if (x.key !== undefined)

Armin Ronacher parece que ya se me adelantó , 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 más seguro, pero la solución más lenta, como se ha señalado por Konrad Rudolph y Armin Ronacher sería la siguiente:

Object.prototype.hasOwnProperty = function(property) {
    return typeof this[property] !== 'undefined';
};
4
  • 2
    No creo que eso sea lo suficientemente bueno. x.hasOwnProperty('toString') === true;Joe Simmons 28 de septiembre de 2013 a las 7:28
  • No pedir estar en desacuerdo, sino entender. ¿Hay algún punto en el que x.hasOwnProperty devuelva algo además de un booleano verdadero o falso? De lo contrario, el código publicado debería funcionar siempre. Supongo que tal vez si se anulara el método, pero entonces, confiar en el resultado nunca sería confiable a menos que conozca el método de anulación. enobrev 29 de septiembre de 2013 a las 15:47
  • 1
    Creo que tenemos una falta de comunicación. Quiero decir que usando su método, diría que 'toString' es su propia propiedad, pero no lo es. Joe Simmons 30 de septiembre de 2013 a las 1:38
  • 3
    Object.prototypeya tiene incorporado, correcto hasOwnProperty. Sobrescribirlo con una implementación incorrecta (1. Las propiedades pueden tener el valor undefined, 2. Esto dará falsos positivos para las propiedades heredadas) es simplemente una idea horriblemente mala. Las respuestas incorrectas pueden y deben eliminarse. No sé si podrías hacer eso en septiembre de 2008 cuando viste la respuesta de Resig , así que comentar para sugerir que lo hagas ahora. T.J. Crowder 18 de septiembre de 2016 a las 8:10
39

Considerando el siguiente objeto en Javascript

const x = {key: 1};

Puede usar el inoperador para verificar si la propiedad existe en un objeto:

console.log("key" in x);

También puede recorrer todas las propiedades del objeto usando un for - inbucle y luego verificar la propiedad específica:

for (const prop in x) {
    if (prop === "key") {
        //Do something
    }
}

Debe considerar si esta propiedad de objeto es enumerable o no, porque las propiedades no enumerables no se mostrarán en un for-inbucle. Además, si la propiedad enumerable está ocultando una propiedad no enumerable del prototipo, no aparecerá en Internet Explorer 8 y versiones anteriores.

Si desea una lista de todas las propiedades de la instancia, ya sean enumerables o no, puede usar

Object.getOwnPropertyNames(x);

Esto devolverá una matriz de nombres de todas las propiedades que existen en un objeto.

Las reflexiones proporcionan métodos que se pueden utilizar para interactuar con objetos Javascript. El Reflect.has()método estático funciona como el operador in como 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, puede usar el operador typeof para verificar directamente el tipo de datos de la propiedad del objeto:

if (typeof x.key === "undefined") {
    console.log("undefined");
}

Si la propiedad no existe en el objeto, devolverá la cadena indefinida. De lo contrario, devolverá el tipo de propiedad apropiado. Sin embargo, tenga en cuenta que esta 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é configurada como indefinida, en cuyo caso, el uso typeof x.keyaún devolvería verdadero (aunque la clave todavía sea en el objeto).

Del mismo modo, puede verificar si existe una propiedad comparándola directamente con la undefinedpropiedad de Javascript

if (x.key === undefined) {
    console.log("undefined");
}

Esto debería funcionar a menos que la clave se haya configurado específicamente undefineden el objeto x

0
31

Eliminemos un poco de confusión aquí. Primero, simplifiquemos asumiendo que hasOwnPropertyya existe; esto es cierto para la gran mayoría de los navegadores que se utilizan actualmente.

hasOwnPropertydevuelve verdadero si el nombre de atributo que se le pasa se ha agregado al objeto. Es completamente independiente del valor real que se le asigna, que puede ser exactamente undefined.

Por eso:

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é sucede cuando un objeto en la cadena de prototipos tiene un atributo con el valor indefinido? hasOwnPropertyserá falso por ello, y también lo será !== undefined. Sin embargo, for..intodavía lo incluirá en la enumeración.

La conclusión es que no hay una forma entre navegadores (ya que Internet Explorer no expone __prototype__) para determinar que no se ha adjuntado un identificador específico a un objeto ni a nada en su cadena de prototipos.

28

Si está buscando una propiedad, entonces "no" . Quieres:

if ('prop' in obj) { }

En general, no debería importarle si la propiedad proviene o no del prototipo o del objeto.

Sin embargo, debido a que usó 'clave' en su código de muestra, parece que está tratando el objeto como un hash, en cuyo caso su respuesta tendría sentido. Todas las claves hash serían propiedades en el objeto y evita las propiedades adicionales aportadas por el prototipo.

La respuesta de John Resig fue muy completa, pero pensé que no estaba clara. Especialmente cuando se usa "'prop' en obj".

3
  • 1
    Tenga en cuenta que el inoperador tiene una excelente compatibilidad con el navegador IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+ stackoverflow.com/questions/2920765/…Adrien Be 15/10/2014 a las 7:38
  • Como se señaló en otro comentario sobre el uso del inoperador: "funciona con 'objetos' en sentido estricto, por lo que se declara como {} o se crea usando el constructor, no acepta matrices o primitivas. No es que el OP lo haya requerido, pero algunas otras respuestas presentan técnicas que son más amplias (trabajar con matrices, cadenas, etc.) "Adrien Be 15/10/2014 a las 7:44
  • 1
    Comentando porque he sido votado en contra dos veces sin comentarios. Pero todavía me gusta mi respuesta. Quizás quien lo hizo quería una respuesta "completa" para todas las formas de probar todo tipo de propiedades. Pero mi respuesta es conceptual y, para eso, sucinta. Re: Adrien Be, una propiedad innumerable es aquella que no está destinada al alcance del usuario general, por lo que conceptualmente 'in' está bien;)Gerard ONeill 27 nov 2017 a las 17:36
20

Para probar objetos simples, use:

if (obj[x] !== undefined)

Si no sabe qué tipo de objeto es, use:

if (obj.hasOwnProperty(x))

Todas las demás opciones son más lentas ...

Detalles

Una evaluación de rendimiento de 100,000,000 ciclos en 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 verificar específicamente la cadena del prototipo del objeto, así como el objeto en sí, no debemos usar la forma común :

if (X in Obj)...

Es entre 2 y 6 veces más lento según el 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 pocas palabras, si su Obj no es necesariamente un objeto simple y desea evitar verificar la cadena del prototipo del objeto y asegurarse de que x sea propiedad de Obj directamente, use if (obj.hasOwnProperty(x))....

De lo contrario, cuando se usa un objeto simple y no se preocupa por la cadena del prototipo del objeto, usar if (typeof(obj[x]) !== 'undefined')...es la forma más segura y rápida.

Si usa un objeto simple como una tabla hash y nunca hace nada pervertido, lo usaría if (obj[x])...ya que lo encuentro mucho más legible.

0
dieciséis

Sí, lo es :) Creo que también puede hacer Object.prototype.hasOwnProperty.call(x, 'key')lo que también debería funcionar si xtiene una propiedad llamada hasOwnProperty:)

Pero eso prueba las propiedades propias. Si desea verificar si tiene una propiedad que también puede ser inherente, puede usarla typeof x.foo != 'undefined'.

dieciséis

También puede utilizar el Reflectobjeto ES6 :

x = {'key': 1};
Reflect.has( x, 'key'); // returns true

La documentación sobre MDN para Reflect.hasse puede encontrar aquí .

The static Reflect.has() method works like the in operator as a function.

0
14
if (typeof x.key != "undefined") {

}

Porque

if (x.key)

falla si se x.keyresuelve en false(por ejemplo, x.key = "").

1
  • 1
    No será correcto. Pruebe el siguiente objeto const x = {key: undefined};que devolverá falso con esta solución, mientras x.hasOwnProperty('key')); // truey Reflect.has(x, 'key')); // true. La propiedad existe realmente, pero el valor es undefined. Wilt 17/10/19 a las 9:02
14

No hagas esto object.hasOwnProperty(key)). Es realmente malo porque estos métodos pueden estar sombreados por propiedades en el objeto en cuestión, considérelo { hasOwnProperty: false }, o el objeto puede ser un objeto nulo (Object.create(null)).

La mejor forma 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));
1
  • 4
    Estoy de acuerdo con este método y debería ser la respuesta aceptada, ya que es la forma más segura mientras se mantiene el rendimiento. eslint.org/docs/rules/no-prototype-builtins dice "Por ejemplo, no sería seguro para un servidor web analizar la entrada JSON de un cliente y llamar a hasOwnProperty directamente en el objeto resultante, porque un cliente malintencionado podría enviar un valor JSON como {"hasOwnProperty": 1} y hace que el servidor se bloquee ". Arman 6/10/19 a las 23:24
11

De acuerdo, parece que tuve la respuesta correcta a menos que no desee 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)
3
  • 4
    Advertencia x.hasOwnProperty ('key') puede ser verdadera mientras que x.key! == undefined no es verdadera. AnthonyWJones 26 de septiembre de 2008 a las 8:34
  • 4
    Porque var x = { key: false };el x.keymétodo sería incorrecto. Mark K Cowan 20/10/2014 a las 9:37
  • 2
    si (x.key) no es correcto como si x = {key: 0}, no pasará la verificación. someUser 19 de septiembre de 2016 a las 8:40
9

Otra forma relativamente sencilla es utilizar Object.keys. Esto devuelve un lo arrayque significa que obtiene todas las características de una matriz.

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 un gran soporte para 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 .

4
  • Correcto, pero ¿y si quisiera saber si info tiene una propiedad con el nombre de otra cosa? Que es lo que OP está buscando. Victorio Berra 26/10/2015 a las 16:40
  • 3
    Entonces haríasObject.keys(info).indexOf('someotherthing') !== -1 ... hippietrail 15 de junio de 2016 a las 4:18
  • ¿Qué es "JS v1.8.5" ? "JavaScript v1.8.5" *? No parece coincidir con ninguna versión de ECMAScript (la versión 8 se lanzó en 2017). jQuery 1.8 fue lanzado en 2012.Peter Mortensen 6/10/20 a las 16:24
  • De acuerdo, JavaScript 1.8.5 se lanzó en 2011 con Firefox 4 (2011-03-22). La primera versión de ECMAScript 5 (vinculada a) es de 2009.Peter Mortensen 6/10/20 a las 16:53
7

hasOwnProperty "se puede utilizar para determinar si un objeto tiene la propiedad especificada como una propiedad directa de ese objeto; a diferencia del operador in , este método no comprueba la cadena de prototipos del objeto".

Así que lo más probable, por lo que parece por su pregunta, usted no desea utilizar hasOwnProperty, que determina si existe la propiedad que se adjunta directamente al objeto en sí mismo ,.

Si desea determinar si la propiedad existe en la cadena del prototipo, es posible que desee utilizarla como:

if (prop in object) { // Do something }
1
  • Aparece "No se puede usar el operador 'in' para buscar 'prop' en myObject"Victorio Berra 26/10/2015 a las 16:42
7

JavaScript ahora está evolucionando y creciendo, ya que ahora tiene formas buenas e incluso eficientes de verificarlo.

A continuación, se muestran algunas formas sencillas de comprobar si el objeto tiene una propiedad en particular :

  1. Utilizando hasOwnProperty()
const hero = {
  name: 'Batman'
};

hero.hasOwnProperty('name');     // => true
hero.hasOwnProperty('realName'); // => false
  1. Usando palabra clave / operador in
const hero = {
  name: 'Batman'
};

'name' in hero;     // => true
'realName' in hero; // => false
  1. Comparando con undefinedpalabra clave
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 obtener más información, consulte aquí .

4

Puede utilizar los siguientes enfoques:

var obj = {a:1}
console.log('a' in obj)               // 1
console.log(obj.hasOwnProperty('a'))  // 2
console.log(Boolean(obj.a))         // 3

La diferencia entre los siguientes enfoques es la siguiente:

  1. En el primer y tercer enfoque no solo buscamos en el objeto, sino también en su cadena prototípica. Si el objeto no tiene la propiedad, pero la propiedad está presente en su cadena de prototipos, dará verdadero.

var obj = {
    a: 2,
    __proto__ : {b: 2}
}

console.log('b' in obj)
console.log(Boolean(obj.b))
  1. El segundo enfoque verificará solo sus propias propiedades. Ejemplo -

var obj = {
    a: 2,
    __proto__ : {b: 2}
}

console.log(obj.hasOwnProperty('b'))
  1. La diferencia entre el primero y el tercero es que si hay una propiedad que tiene un valor indefinido, el tercer enfoque dará falso mientras que el primero dará verdadero.

var obj = {
    b : undefined
}

console.log(Boolean(obj.b))
console.log('b' in obj);
2
  • Boolean({b:''}.b) -> falseKamil Kiełczewski 15/12/20 a las 20:29
  • @ KamilKiełczewski sí, se supone que debe dar falso, cualquier valor falso en este caso devolverá falsoKomal Bansal 16 de diciembre de 2020 a las 4:56
3

Aquí hay otra opción para un caso específico. :)

Si desea probar un miembro en un objeto y desea saber si se ha configurado en algo diferente a:

  • ''
  • falso
  • nulo
  • indefinido
  • 0 ...

entonces puedes usar:

var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
    // member is set, do something
}
2
3

Rendimiento

Hoy 2020.12.17 realizo pruebas en MacOs HighSierra 10.13.6 en Chrome v87, Safari v13.1.2 y Firefox v83 para las soluciones elegidas.

Resultados

Comparo solo las soluciones AF porque dan un resultado válido para todas las mayúsculas utilizadas en el fragmento en la sección de detalles. Para todos los navegadores

  • la solución basada en in(A) es rápida o más rápida
  • La solución (E) es la más rápida para Chrome para objetos grandes y la más rápida para Firefox para matrices pequeñas si la clave no existe.
  • La solución (F) es más rápida (~> 10 veces que otras soluciones) para arreglos pequeños
  • las soluciones (D, E) son bastante rápidas
  • La solución basada en losash has(B) es la más lenta.

ingrese la descripción de la imagen aquí

Detalles

Realizo 4 casos de prueba:

  • cuando el objeto tiene 10 campos y existe la clave buscada, puede ejecutarlo AQUÍ
  • cuando el objeto tiene 10 campos y la clave buscada no existe, puede ejecutarla AQUÍ
  • cuando el objeto tiene 10000 campos y existe la clave buscada, puede ejecutarlo AQUÍ
  • cuando el objeto tiene 10000 campos y existe la clave buscada, puede ejecutarlo AQUÍ

El siguiente fragmento presenta las diferencias entre las soluciones A B C D E F G H I J K

// SO https://stackoverflow.com/q/135448/860099


// src: https://stackoverflow.com/a/14664748/860099
function A(x) {
  return 'key' in x
}

// src: https://stackoverflow.com/a/11315692/860099
function B(x) {
  return _.has(x, 'key')
}

// src: https://stackoverflow.com/a/40266120/860099
function C(x) {
  return Reflect.has( x, 'key')
}

// src: https://stackoverflow.com/q/135448/860099
function D(x) {
  return x.hasOwnProperty('key')
}

// src: https://stackoverflow.com/a/11315692/860099
function E(x) {
  return Object.prototype.hasOwnProperty.call(x, 'key')
}

// src: https://stackoverflow.com/a/136411/860099
function F(x) {
  function hasOwnProperty(obj, prop) {
      var proto = obj.__proto__ || obj.constructor.prototype;
      return (prop in obj) &&
          (!(prop in proto) || proto[prop] !== obj[prop]);
  }
  return hasOwnProperty(x,'key')
}

// src: https://stackoverflow.com/a/135568/860099
function G(x) {
  return typeof(x.key) !== 'undefined'
}

// src: https://stackoverflow.com/a/22740939/860099
function H(x) {
  return x.key !== undefined
}

// src: https://stackoverflow.com/a/38332171/860099
function I(x) {
  return !!x.key
}

// src: https://stackoverflow.com/a/41184688/860099
function J(x) {
  return !!x['key']
}

// src: https://stackoverflow.com/a/54196605/860099
function K(x) {
  return Boolean(x.key)
}


// --------------------
// TEST
// --------------------

let x1 = {'key': 1};
let x2 = {'key': "1"};
let x3 = {'key': true};
let x4 = {'key': []};
let x5 = {'key': {}};
let x6 = {'key': ()=>{}};
let x7 = {'key': ''};
let x8 = {'key': 0};
let x9 = {'key': false};
let x10= {'key': undefined};
let x11= {'nokey': 1};



let b= x=> x ? 1:0;

console.log('  1 2 3 4 5 6 7 8 9 10 11');

[A,B,C,D,E,F,G,H,I,J,K ].map(f=> {  
  console.log(
    `${f.name} ${b(f(x1))} ${b(f(x2))} ${b(f(x3))} ${b(f(x4))} ${b(f(x5))} ${b(f(x6))} ${b(f(x7))} ${b(f(x8))} ${b(f(x9))} ${b(f(x10))}  ${b(f(x11))} `
  )})
  
console.log('\nLegend: Columns (cases)');
console.log('1.  key = 1 ');
console.log('2.  key = "1" ');
console.log('3.  key = true ');
console.log('4.  key = [] ');
console.log('5.  key = {} ');
console.log('6.  key = ()=>{} ');
console.log('7.  key = "" ');
console.log('8.  key = 0 ');
console.log('9.  key = false ');
console.log('10. key = undefined ');
console.log('11. no-key ');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
  
This shippet only presents functions used in performance tests - it not perform tests itself!

Y aquí hay resultados de ejemplo para Chrome.

ingrese la descripción de la imagen aquí

2

Hay un método, "hasOwnProperty", que existe en un objeto, pero no se recomienda llamar a este método directamente, porque a veces puede ser que el objeto sea nulo o que exista alguna propiedad en el objeto como: { hasOwnProperty: false }

Entonces, una mejor manera sería:

// Good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));

// Best
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));
2

Una solución ECMAScript 6 con reflexión. Crea una envoltura como:

/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
@param obj    The object or array to be searched.
@param key    The name of the property or key.
@param defVal Optional default version of the command-line parameter [default ""]
@return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
   "use strict";
   var retVal = (typeof defVal === 'undefined' ? "" : defVal);
   if ( Reflect.has( obj, key) ) {
       return Reflect.get( obj, key);
   }
   return retVal;
}  // getSafeReflectArg
3
  • ¿Es esta la mejor manera de hacerlo cuando se orienta a> = ES6? hippietrail 30 de agosto de 2017 a las 4:36
  • 1
    En mi humilde opinión, es la respuesta más corta y simple, pero tal vez no sea la más rápida en el código de ejecución. Pero la velocidad ya no es un problema. Harm 31/08/17 a las 14:20
  • ¿Por qué publicar la misma respuesta dos veces? ¿Podrías simplemente votar a favor del existente ...? Wilt 19 nov.20 a las 19:15
2

Dada myObject objeto y “myKey” como nombre de la clave:

Object.keys(myObject).includes('myKey')

o

myObject.hasOwnProperty('myKey')

o

typeof myObject.myKey !== 'undefined'

El último fue ampliamente utilizado, pero (como se señaló en otras respuestas y comentarios) también podría coincidir con claves derivadas del prototipo de objeto.

1

Necesitas usar el método object.hasOwnProperty(property). Devuelve verdadero si el objeto tiene la propiedad y falso si el objeto no la tiene.

1

Mostrando cómo usar esta respuesta

const object= {key1: 'data', key2: 'data2'};

Object.keys(object).includes('key1') //returns true

También podemos usar indexOf, yo prefiero incluye

1

El método hasOwnProperty () devuelve un valor booleano que indica si el objeto tiene la propiedad especificada como su propia propiedad (en lugar de heredarla).

const object1 = {};
object1.property1 = 42;

console.log(object1.hasOwnProperty('property1'));
// expected output: true

console.log(object1.hasOwnProperty('toString'));
// expected output: false

console.log(object1.hasOwnProperty('hasOwnProperty'));
// expected output: false

Saber más

0

No complique demasiado las cosas cuando puede hacer:

var isProperty =  (objectname.keyname || "") ? true : false;

Es simple y claro para la mayoría de los casos ...

2
  • El más simple es var isProperty = !! objectname.keyname; John 24/01/19 a las 7:04
  • 1
    Si el objeto es el siguiente const objectName = { keyname: false };, debería devolver verdadero, ya que keynamees una propiedad de objectname. Pero dado que el valor es falso, devolvería falso con esta lógica. Wilt 17/10/19 a las 8:53
0

Un mejor enfoque para iterar en las propias propiedades del objeto:

Si desea iterar en las propiedades del objeto sin usar la hasOwnProperty()verificación, use el for(let key of Object.keys(stud)){}método:

for(let key of Object.keys(stud)){
  console.log(key); // will only log object's Own properties
}

Ejemplo completo y comparación con for-in with hasOwnProperty()

function Student() {
  this.name = "nitin";
}

Student.prototype = {
  grade: 'A'
}

let stud = new Student();

// for-in approach
for(let key in stud){
  if(stud.hasOwnProperty(key)){
    console.log(key); // only outputs "name"
  }
} 

//Object.keys() approach
for(let key of Object.keys(stud)){
  console.log(key);
}
0

algunas opciones más fáciles y breves según el caso de uso específico:

  1. para comprobar si la propiedad existe, independientemente del valor, utilice el operador in ("a" en b)
  2. para verificar el valor de una propiedad de una variable, use la notación entre corchetes (obj [v])
  3. para verificar el valor de una propiedad como veraz, use el encadenamiento opcional (?.)
  4. para verificar un valor de propiedad booleano, use double-not / bang-bang / (!!)
  5. para establecer un valor predeterminado para la verificación nula / indefinida, use el operador de fusión nula (??)
  6. para establecer un valor predeterminado para la verificación del valor falsey, use el operador OR lógico de cortocircuito (||)

ejecute el fragmento de código para ver los resultados:

let obj1 = {prop:undefined};
console.log(1,"prop" in obj1);
console.log(1,obj1?.prop);

let obj2 = undefined;
//console.log(2,"prop" in obj2); would throw because obj2 undefined
console.log(2,"prop" in (obj2 ?? {}))
console.log(2,obj2?.prop);

let obj3 = {prop:false};
console.log(3,"prop" in obj3);
console.log(3,!!obj3?.prop);

let obj4 = {prop:null};
let look = "prop"
console.log(4,"prop" in obj4);
console.log(4,obj4?.[look]);

let obj5 = {prop:true};
console.log(5,"prop" in obj5);
console.log(5,obj5?.prop === true);

let obj6 = {otherProp:true};
look = "otherProp"
console.log(6,"prop" in obj6);
console.log(6,obj6.look); //should have used bracket notation

let obj7 = {prop:""};
console.log(7,"prop" in obj7);
console.log(7,obj7?.prop || "empty"); 

Veo muy pocos casos en los que hasOwnse usa correctamente, especialmente dados sus problemas de herencia.