2012-10-04 9 views
51

Duplicar posible:
How do I check to see if an object has a property in Javascript?for..in y hasOwnProperty

encontré el siguiente fragmento de archivos JS de Twitter. Me preguntaba por qué necesitan llamar a la función hasOwnProperty para ver que 'dict' tiene la propiedad 'clave'. El bucle for se ejecuta para cada 'clave' en 'dict', que significa 'dict' tiene 'clave', ¿me falta un punto?

function forEach(dict, f) { 
    for (key in dict) { 
     if (dict.hasOwnProperty(key)) 
      f(key, dict[key]); 
    } 
} 
+3

Está bien explicado aquí: http://stackoverflow.com/a/136411/27512 – kevingessner

+0

Parece que 'key' es global, ¿de dónde es este código, puede publicar un enlace a él? – elclanrs

+0

@elclanrs Estaba equivocado. Este código es de utils.js de Chrome. Js – scusyxx

Respuesta

54

Porque si no lo hace, se hará un bucle a través de cada propiedad en la cadena de prototipo, incluidos los que no conocen (que posiblemente se añadieron por alguien jugar con prototipos de objetos nativos).

De esta manera, se le garantizan solo las claves que están en la instancia del objeto en sí.

+0

Muchas gracias. Tiene más sentido ahora ... – scusyxx

5

Cada objeto en Javascript es un diccionario, esto significa que "toString" y todos los demás métodos es un determinante de cualquier objeto

var myObj = {}; 
console.log(myObj["toString"]); 

Pero esta función se hereda de la clase Object, por lo hasOwnProperty le indica si esta la clave es propiedad del diccionario o si se hereda.

"toString" in myObj; // true 
myObj.hasOwnProperty("toString") // false 
1

@blockhead es aquí. Por ejemplo, el marco Prototype.js utilizado para extender matrices nativas con métodos adicionales de ayuda (no conozco la situación con las versiones actuales de un marco). Por lo tanto, el uso directo de "for (key in dict)" devolvería todos los elementos de las referencias div plus a los métodos auxiliares. Lo cual es un poco inesperado :)

26

El método hasOwnProperty le permite saber si una propiedad está directamente en una instancia de un objeto o se hereda de su cadena de prototipo.

Considere lo siguiente

function ObjWithProto() { 
    this.foo = 'foo_val'; 
} 

ObjWithProto.prototype = {bar: 'bar_val'}; 

var dict = new ObjWithProto(); 
dict.foobar = 'foobar_val'; 

es decir, que tienen un objeto dict con propiedades foo y foobar que también hereda una propiedad bar de ella de cadena de prototipo.

Ahora ejecutarlo a través de (una versión modificada de) su código

function forEach(dict) { 
    var key; 
    for (key in dict) { 
     if (dict.hasOwnProperty(key)) console.log('has', key, dict[key]); 
     else console.log('not', key, dict[key]); 
    } 
} 
forEach(dict); 

verá

has foo foo_val 
has foobar foobar_val 
not bar bar_val 

Esto le permite propiedades separadas que un objeto tiene en sí y para los que ha heredado (que generalmente son métodos que no son relevantes para el ciclo)

Además, si ahora hace dict.bar = 'new_bar_val';, el último resultado cambiará a has bar new_bar_val, lo que le permite distinguir incluso entre las propiedades del mismo nombre que las heredadas.

Cuestiones relacionadas