En JavaScript tenemos algunas formas de obtener las propiedades de un objeto, dependiendo de lo que queramos obtener.
1) Object.keys()
, que devuelve todas las propiedades enumerables propias de un objeto, un método ECMA5.
2) un for...in
bucle, que devuelve todas las propiedades enumerables de un objeto, independientemente de si son propiedades propias o heredadas de la cadena del prototipo.
3) Object.getOwnPropertyNames(obj)
que devuelve todas las propiedades propias de un objeto, enumerables o no.
También tenemos métodos que hasOwnProperty(prop)
nos permiten verificar si una propiedad es heredada o realmente pertenece a ese objeto, y propertyIsEnumerable(prop)
que, como sugiere el nombre, nos permite verificar si una propiedad es enumerable.
Con todas estas opciones, no hay forma de obtener una propiedad no enumerable ni propia de un objeto, que es lo que quiero hacer. ¿Hay alguna forma de hacer esto? En otras palabras, ¿puedo de alguna manera obtener una lista de las propiedades heredadas no enumerables?
Gracias.
fuente
Respuestas:
Dado que
getOwnPropertyNames
puede obtener propiedades no enumerables, puede usar eso y combinarlo con subir la cadena del prototipo.Probé eso en Safari 5.1 y obtuve
Actualización: se refactorizó un poco el código (se agregaron espacios y llaves, y se mejoró el nombre de la función):
fuente
while(curr = Object.getPrototypeOf(cure))
ya que la declaración condicional usa un operador de asignación en lugar de un operador de comparación, ¿esto no siempre devolvería verdadero? ¿O esta línea esencialmente verifica si "curr" tiene un prototipo?Object.getPrototypeOf(cure)
regresenull
en la parte superior de la cadena de prototipos. ¡Supongo que esto supone que no hay cadenas de prototipos circulares!Function.prototype
nunca puede ser el prototipo "raíz", ya que su enlace de prototipo apunta aObject.prototype
. La funciónObject.getPrototypeOf( obj )
devuelve el objeto superior en la cadena de prototipos deobj
. Le permite seguir la cadena de prototipos deobj
hasta llegar a su final (elnull
valor). No estoy seguro de cuál es su problema con esto ...undefined
.Object.getPrototypeOf(John)
devuelve elBoy.prototype
objeto (como debería); consulte aquí: jsfiddle.net/aeGLA/1 . Tenga en cuenta que el constructor noBoy
está en la cadena de prototipos de . La cadena de prototipo es el siguiente: .John
John
Boy.prototype -> Object.prototype -> null
John
, su constructor esBoy
, y laprototype
propiedad deBoy
esBoy.prototype
. Así queObject.getPrototypeOf(John)
vuelveBoy.prototype
.Una solución más limpia usando recursividad:
Editar
Funciones más genéricas:
Esta misma plantilla se puede aplicar usando
Object.getOwnPropertySymbols
, etc.fuente
Aprovechar los conjuntos conduce a una solución algo más limpia, en mi opinión.
fuente
Iterativo directo en ES6:
Ejecución de ejemplo:
Mostrar fragmento de código
fuente
Para obtener todas las propiedades o métodos heredados para alguna instancia, puede usar algo como esto
fuente
Object.getInherited
lugar deObject.prototype.getInherited
. Hacer eso también elimina la necesidad del!(name == 'getInherited')
cheque feo . Además, en su implementación, laprops
matriz puede contener propiedades duplicadas. Por último, ¿cuál es el propósito de ignorar laconstructor
propiedad?Aquí está la solución que se me ocurrió mientras estudiaba el tema. Para obtener todas las propiedades no propias no enumerables del
obj
objeto, hagagetProperties(obj, "nonown", "nonenum");
fuente
Ejemplo de uso:
fuente
si está intentando registrar propiedades no enumerables de un objeto principal, ej. de forma predeterminada, los métodos definidos dentro de una clase en es6 se establecen en el prototipo, pero se establecen como no enumerables.
fuente
Una implementación en mis preferencias personales :)
fuente