2012-02-09 14 views
6

Así que tengo el objeto vacío a = {}. Cuando hago console.log(a), console.dir(a), o inclusoImprimir todas las propiedades ocultas de un objeto

for(b in a) { 
    console.log(b); 
} 

no consigo ver las "propiedades ocultas", como __defineGetter__, hasOwnProperty, etc.

¿Cómo puedo imprimir todas las propiedades de un objeto ?

+0

¿Qué navegador ha utilizado? En Google Chrome veo todas las propiedades del objeto – antyrat

+0

@antyrat. Estoy usando Google Chrome 17 y la única propiedad que veo usando 'console.log' es' __proto__'. – Randomblue

+0

Puede abrir esta propiedad y dentro de ella verá todas las propiedades no enumerables – antyrat

Respuesta

12

Lo que buscas son las propiedades non-enumerable de un objeto (y posiblemente las que hereda de su prototipo). No creo que haya una forma estándar de obtenerlos a través de JavaScript.

Si usa un depurador e inspecciona un objeto, generalmente se muestran todas las propiedades de un objeto (no solo las enumerables). Todos los principales navegadores tienen depurados incorporados ahora: Chrome tiene herramientas de desarrollo (Ctrl + Shift + I); IE8 y superior tienen "Herramientas de desarrollo F12"; IE7 y versiones anteriores se pueden depurar a través de la versión gratuita de VS.Net; las versiones recientes de Firefox tienen herramientas integradas; para las versiones anteriores, puede obtener el complemento Firebug; Opera tiene Libélula.

actualización: En los comentarios sobre la cuestión que ha dicho:

estoy usando Google Chrome 17 y la única propiedad que veo usando console.log es __proto__.

Derecha. {} no tiene propiedades en absoluto, solo un prototipo. Si hace clic en la pequeña flecha a la izquierda de __proto__, le mostrará las propiedades de __proto__. hasOwnProperty, toString, etc., son todas las propiedades {} que se obtienen del prototipo (que es Object.prototype), no las propiedades del objeto en sí.

JavaScript usa prototipo de herencia, lo que significa que un objeto está respaldado por un prototipo. Si intenta recuperar el valor de una propiedad que el objeto no tiene, el motor de JavaScript mirará el prototipo del objeto para ver si el prototipo tiene esa propiedad; si es así, ese valor se usa. Si el prototipo no lo tiene, el motor mira el prototipo del prototipo; y así sucesivamente hasta llegar a la raíz de la jerarquía. Esta es la razón por la que escuchas que los objetos tienen sus propias propiedades en comparación con las propiedades que heredan.

He aquí un ejemplo:

Aquí es una función constructora. Ponemos una propiedad en el prototipo que asignará el motor de JavaScript si usamos new Foo para crear un objeto.

function Foo() { 
} 
Foo.prototype.bar = 42; 

Vamos a crear un objeto utilizando ese constructor:

var f = new Foo(); 

f no tiene propiedades en absoluto, y, sin embargo:

console.log(f.bar); // 42 

...porque desde f no tiene una propiedad llamada "barra", el motor se ve en el prototipo f, que es el objeto Foo.prototype.

Ahora vamos a darle f su propia propiedad "barra":

f.bar = 67; 
console.log(f.bar); // 67 

Ahora vamos a eliminarf 's propiedad "bar":

delete f.bar; 

¿Qué pasará si tratamos de recuperar f.bar ahora?

console.log(f.bar); 

Si dijo 42, obtiene las mejores calificaciones. Como f ya no tiene una propiedad llamada "barra", volvemos a obtenerla del prototipo.

Tenga en cuenta que esta relación es vivo, por lo que:

Foo.prototype.bar = 96; 
console.log(f.bar); // 96 

En la 3ª edición de ECMAScript (la mayoría de los navegadores implementan algo en la línea de la 3ª edición), la única manera de asignar un prototipo de un objeto es a través de la propiedad prototype de una función de constructor, como se indicó anteriormente. Con la quinta edición, se añadió una manera más directa: Object.create, que puede pasar un objeto prototipo a directamente:

var proto = {bar: 42}; 
var obj = Object.create(proto); 
console.log(obj.bar); // 42 
proto.bar = 67; 
console.log(obj.bar); // 67 
+0

Muy bien escrito (+1), gracias :) – nkm

3

Object.getOwnPropertyNames (obj) también mostrará todos los bienes no numerable, aunque no seguirá la búsqueda prototype chain como . hace.

No conozco ningún método que suba la cadena del prototipo y muestre no enumerables.

Ejemplo:

var o = Object.create({base:0}) 
Object.defineProperty(o, 'yes', {enumerable: true}) 
Object.defineProperty(o, 'not', {enumerable: false}) 

console.log(Object.getOwnPropertyNames(o)) 
// [ 'yes', 'not' ] 

console.log(Object.keys(o)) 
// [ 'not' ] 

for (var x in o) 
    console.log(x) 
// yes, base 

Así llegamos a la conclusión:

  • Object.keys() no sube la cadena, y no muestra los no enumerables
  • for in sube la cadena, pero no muestra no enumerables

Podría, por supuesto, Subir manualmente la cadena del prototipo y usar Object.getOwnPropertyNames.

Para el caso de Object, __defineGetter__ y hasOwnProperty son propiedades de Object.prototype conocer en new Object objetos a través de las operaciones de búsqueda cadena de prototipo. Así que se podría conseguir con:

console.log(Object.getOwnPropertyNames(Object.prototype)) 

Salida:

[ 'constructor', 
    'toString', 
    'toLocaleString', 
    'valueOf', 
    'hasOwnProperty', 
    'isPrototypeOf', 
    'propertyIsEnumerable', 
    '__defineGetter__', 
    '__lookupGetter__', 
    '__defineSetter__', 
    '__lookupSetter__' ] 
Cuestiones relacionadas