2012-06-10 8 views
18

Puede alguien me ilumine, ¿cuál es la diferencia entre hasOwnProperty y propertyIsEnumerable:hasOwnProperty vs propertyIsEnumerable

function f(){ 
    this.a = 1; 
    this.b = 2; 
    this.c = function(){} 
} 
f.prototype = { 
    d : 3, 
    e : 4, 
    g : function(){} 
} 

creación de la instancia de un objeto:

var o = new f(); 

Y aquí no puedo ver la diferencia . En mi opinión, están haciendo lo mismo

o.hasOwnProperty('a'); //true 
o.hasOwnProperty('b'); //true 
o.hasOwnProperty('c'); //true 
o.hasOwnProperty('d'); //false 
o.hasOwnProperty('e'); //false 
o.hasOwnProperty('g'); //false 

o.propertyIsEnumerable('a'); //true 
o.propertyIsEnumerable('b'); //true 
o.propertyIsEnumerable('c'); //true 
o.propertyIsEnumerable('d'); //false 
o.propertyIsEnumerable('e'); //false 
o.propertyIsEnumerable('g'); //false 

derecho conmigo si estoy equivocado

Respuesta

27

La función "propertyIsEnumerable" siempre excluye propiedades que no volverían true para "hasOwnProperty". No ha hecho nada para que ninguna propiedad sea enumerable, por lo que en su prueba los resultados son los mismos.

Puede usar "defineProperty" para definir las propiedades que son no enumerable; see this reference en MDN.

Object.defineProperty(obj, "hideMe", { value: null, enumerable: false }); 

Eso es como:

obj.hideMe = null; 

excepto la propiedad no se mostrarán en for ... in bucles, y las pruebas con propertyIsEnumerable regresará false.

Todo este tema trata de funciones que no están disponibles en los navegadores antiguos, si eso no es obvio.

3

La diferencia es que propertyIsEnumerable devuelve true sólo si existe la propiedad y si es posible hacer Forin en la propiedad, hasOwnProperty devolverá verdadero si existe la propiedad independientemente de apoyo Forin

De MSDN:

El método propertyIsEnumerable devuelve verdadero si proName existe en el objeto y se puede enumerar utilizando un bucle ForIn. El método propertyIsEnumerable devuelve falso si el objeto no tiene una propiedad del nombre especificado o si la propiedad especificada no es enumerable. Normalmente, las propiedades predefinidas no son enumerables, mientras que las propiedades definidas por el usuario son siempre enumerables.

El método hasOwnProperty devuelve verdadero si el objeto tiene una propiedad del nombre especificado , falso si no es así. Este método no verifica si la propiedad existe en la cadena de prototipos del objeto; la propiedad debe ser ser un miembro del objeto en sí.

20

hasOwnProperty volverá true incluso para los no-enumerables propiedades "propios" (como length en un Array). propertyIsEnumerable devolverá true solo para enumerable propiedades "propias". (Una propiedad "enumerable" es una propiedad que aparece en for..in loops y tal.)

Ejemplo:

var a = []; 
 
snippet.log(a.hasOwnProperty('length'));  // "true" 
 
snippet.log(a.propertyIsEnumerable('length')); // "false"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

o con un objeto no array:

var o = {}; 
 
Object.defineProperty(o, "foo", { enumerable: false }); 
 
snippet.log(o.hasOwnProperty('foo'));  // "true" 
 
snippet.log(o.propertyIsEnumerable('foo')); // "false"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

(Cuando se utiliza Object.defineProperty, enumerable por defecto false, pero he estado explícita de arriba para mayor claridad)

+0

Esta explicación está más claro que la respuesta aceptada. – mareoraft

5

En pocas palabras:.

hasOwnProperty volverá verdadero si y sólo si la propiedad es la propiedad del objeto y no es heredado. Este es simple.

y

propertyIsEnumerable volverá verdadero si y sólo si hasOwnProperty devuelve true y la propiedad es numerable. Entonces, propertyIsEnumerable es un "requisito adicional" además de la prueba hasOwnProperty, y el nombre propertyIsEnumerable sería más preciso si es hasOwnPropertyAndIsEnumerable.

demo: http://jsfiddle.net/aby3k/

+0

¡Gracias por el resumen conciso! Entonces, usaré propertyIsEnumerable cuando quiera ser extremadamente estricto, entonces hasOwnProperty no es necesario. He estado viendo "hasOwnProperty" usado mucho al filtrar los bucles "key in obj", pero rara vez "propertyIsEnumerable" ... –

Cuestiones relacionadas