¿Las siguientes dos declaraciones producen el mismo resultado? ¿Hay alguna razón para preferir un camino al otro?
if (key in object)
if (object.hasOwnProperty(key))
¿Las siguientes dos declaraciones producen el mismo resultado? ¿Hay alguna razón para preferir un camino al otro?
if (key in object)
if (object.hasOwnProperty(key))
Respuestas:
Tenga cuidado, no producirán el mismo resultado.
intambién regresará truesi keyse encuentra en algún lugar de la cadena del prototipo , mientras que Object.hasOwnProperty(como el nombre ya nos dice), solo regresará truesi keyestá disponible en ese objeto directamente (es "dueño" de la propiedad).
({foo:"bar"}).hasOwnProperty("toString")vs"toString" in ({foo:"bar"})
Trataré de explicar con otro ejemplo. Digamos que tenemos el siguiente objeto con dos propiedades:
function TestObj(){
this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';
Creemos una instancia de TestObj:
var o = new TestObj();
Examinemos la instancia del objeto:
console.log(o.hasOwnProperty('name')); // true
console.log('name' in o); // true
console.log(o.hasOwnProperty('gender')); // false
console.log('gender' in o); // true
Conclusión:
en operador devuelve verdadero siempre, si el objeto puede acceder a la propiedad, directamente o desde el prototipo
hasOwnProperty () devuelve verdadero solo si la propiedad existe en la instancia, pero no en su prototipo
Si queremos verificar que exista alguna propiedad en el prototipo, lógicamente, diríamos:
console.log(('name' in o) && !o.hasOwnProperty('name')); //false
console.log(('gender' in o) && !o.hasOwnProperty('gender')); //true - it's in prototype
Finalmente:
Entonces, con respecto a la declaración de que estas dos condiciones ...
if (key in object)
if (object.hasOwnProperty(key))
... produce el mismo resultado, la respuesta es obvia, depende.
intambién verificará las propiedades heredadas, lo cual no es el caso hasOwnProperty.
En resumen, hasOwnProperty()no se ve en el prototipo mientras inse ve en el prototipo.
Tomado de O'Reilly High Performance Javascript :
Puede determinar si un objeto tiene un miembro de instancia con un nombre dado usando el método hasOwnProperty () y pasando el nombre del miembro. Para determinar si un objeto tiene acceso a una propiedad con un nombre de pila, puede usar el operador in. Por ejemplo:
var book = {
title: "High Performance JavaScript",
publisher: "Yahoo! Press"
};
alert(book.hasOwnProperty("title")); //true
alert(book.hasOwnProperty("toString")); //false
alert("title" in book); //true
alert("toString" in book); //true
En este código, hasOwnProperty () devuelve verdadero cuando se pasa "título" porque el título es una instancia de objeto; el método devuelve falso cuando se pasa "toString" porque no existe en la instancia. Cuando se usa cada nombre de propiedad con el operador in, el resultado es verdadero las dos veces porque busca la instancia y el prototipo.
Tienes algunas respuestas realmente geniales. Solo quiero ofrecer algo que le ahorrará la necesidad de marcar "hasOwnProperty" mientras itera un objeto.
Al crear un objeto, generalmente las personas lo crearán de esta manera:
const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }
Ahora, si desea iterar a través de "someMap", deberá hacerlo de esta manera:
const key
for(key in someMap ){
if (someMap.hasOwnProperty(key)) {
// Do something
}
}
Lo estamos haciendo para evitar iterar sobre propiedades heredadas.
Si tiene la intención de crear un objeto simple que solo se utilizará como un "mapa" (es decir, pares clave-valor), puede hacerlo así:
const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined
Así que ahora será seguro iterar así:
for(key in cleanMap){
console.log(key + " -> " + newMap [key]);
// No need to add extra checks, as the object will always be clean
}
Aprendí este increíble consejo aquí
La otra forma (solicitada en) enumera los nombres de propiedad (o claves) de un objeto. En cada iteración, se asigna otra cadena de nombre de propiedad del objeto a la variable. Por lo general, es necesario probar object.hasOwnProperty (variable) para determinar si el nombre de la propiedad es realmente un miembro del objeto o si se encontró en su lugar en la cadena del prototipo.
for (myvar in obj) {
if (obj.hasOwnProperty(myvar)) { ... } }
(del Javascript de Crockford : las partes buenas )
inoperador es diferente a la for-indeclaración.
ines una palabra clave. Pero OP pregunta sobre el uso específico como inoperador. Su respuesta trata con el otro uso como parte de la for-indeclaración.
La primera versión es más corta (especialmente en código minificado donde las variables cambian de nombre)
a in b
vs
b.hasOwnProperty(a)
De todos modos, como dijo @AndreMeinhold, no siempre producen el mismo resultado.
in will also return true if key gets found somewhere in the prototype chain? puedes escribir un ejemplo? Gracias.