Puede usar Object.getOwnPropertyNames()
para obtener todas las propiedades que pertenecen a un objeto, ya sean enumerables o no. Por ejemplo:
console.log(Object.getOwnPropertyNames(Math));
//-> ["E", "LN10", "LN2", "LOG2E", "LOG10E", "PI", ...etc ]
Luego puede usar filter()
para obtener solo los métodos:
console.log(Object.getOwnPropertyNames(Math).filter(function (p) {
return typeof Math[p] === 'function';
}));
//-> ["random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", ...etc ]
En los navegadores ES3 (IE 8 y versiones anteriores), las propiedades de los objetos integrados no son enumerables. Los objetos como window
y document
no están integrados, están definidos por el navegador y probablemente enumerables por diseño.
Desde ECMA-262 Edición 3 :
Objeto global
Hay un objeto global único (15.1), que se crea antes de que el control entre en cualquier contexto de ejecución. Inicialmente, el objeto global tiene las siguientes propiedades:
• Objetos integrados como Math, String, Date, parseInt, etc. Estos tienen atributos {DontEnum} .
• Propiedades definidas por el host adicionales. Esto puede incluir una propiedad cuyo valor es el objeto global en sí mismo; por ejemplo, en el modelo de objeto de documento HTML, la propiedad de ventana del objeto global es el objeto global en sí.
A medida que el control ingresa en contextos de ejecución, y a medida que se ejecuta el código ECMAScript, se pueden agregar propiedades adicionales al objeto global y se pueden cambiar las propiedades iniciales.
Debo señalar que esto significa que esos objetos no son propiedades enumerables del objeto Global. Si mira el resto del documento de especificación, verá que la mayoría de las propiedades y métodos integrados de estos objetos tienen el { DontEnum }
atributo establecido en ellos.
Actualización: otro usuario de SO, CMS, trajo un error de IE con respecto{ DontEnum }
a mi atención.
En lugar de verificar el atributo DontEnum, [Microsoft] JScript omitirá cualquier propiedad en cualquier objeto donde haya una propiedad con el mismo nombre en la cadena prototipo del objeto que tenga el atributo DontEnum.
En resumen, tenga cuidado al nombrar las propiedades de su objeto. Si hay una propiedad o método prototipo incorporado con el mismo nombre, IE lo omitirá cuando use un for...in
bucle.
Object.getOwnPropertyNames()
, lo que devolverá incluso propiedades y métodos no enumerables.Object.getOwnPropertyNames(Array.prototype)
?No es posible con ES3 ya que las propiedades tienen un
DontEnum
atributo interno que nos impide enumerar estas propiedades. ES5, por otro lado, proporciona descriptores de propiedades para controlar las capacidades de enumeración de propiedades para que las propiedades nativas y definidas por el usuario puedan usar la misma interfaz y disfrutar de las mismas capacidades, lo que incluye poder ver las propiedades no enumerables mediante programación.La
getOwnPropertyNames
función se puede usar para enumerar todas las propiedades del objeto pasado, incluidas las que no se pueden enumerar. Luego,typeof
se puede emplear una simple verificación para filtrar las no funciones. Desafortunadamente, Chrome es el único navegador en el que funciona actualmente.registra
["cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"]
sin ningún orden en particular.fuente
De esta manera, obtendrá todos los métodos a los que puede recurrir
obj
. Esto incluye los métodos que "hereda" de su prototipo (comogetMethods()
en Java). Si solo desea ver los métodos definidos directamente porobj
usted, puede consultar conhasOwnProperty
:fuente
document
o tengowindow
más suerte. Francamente, es un poco inesperado, no sé por qué no funciona para Matemáticas, etc.document
ywindow
son objetos con propiedades enumerables proporcionadas por el navegador, no son parte del tiempo de ejecución de secuencias de comandos. Los objetos nativos son y obviamente las propiedades no son enumerables.El soporte de navegador más moderno
console.dir(obj)
, que devolverá todas las propiedades de un objeto que heredó a través de su constructor. Consulte la documentación de Mozilla para obtener más información y soporte actual del navegador.fuente
Las otras respuestas aquí funcionan para algo como Math, que es un objeto estático. Pero no funcionan para una instancia de un objeto, como una fecha. Encontré lo siguiente para trabajar:
https://jsfiddle.net/3xrsead0/
Esto no funcionará para algo como la pregunta original (Matemáticas), así que elija su solución según sus necesidades. Estoy publicando esto aquí porque Google me envió a esta pregunta, pero quería saber cómo hacer esto para instancias de objetos.
fuente
La respuesta corta es que no puedes porque
Math
yDate
(fuera de mi cabeza, estoy seguro de que hay otros) no son objetos normales. Para ver esto, cree un script de prueba simple:Verá que se presenta como un objeto de la misma manera que lo hace el documento en general, pero cuando realmente intenta ver ese objeto, ve que es un código nativo y algo que no está expuesto de la misma manera para la enumeración.
fuente
Math
tiene un método estático donde puede llamar directamenteMath.abs()
mientras queDate
tiene un método estático comoDate.now()
y también un método de instancia donde primero necesita crear una nueva instanciavar time = new Date()
para llamartime.getHours()
.Por supuesto, necesitará filtrar las claves obtenidas para el método estático para obtener nombres de métodos reales, porque también puede obtener
length, name
que no sean una función en la lista.Pero, ¿cómo si queremos obtener todos los métodos disponibles de la clase que extienden otra clase?
Por supuesto, tendrá que escanear a través de la raíz del prototipo como usar
__proto__
. Para ahorrar tiempo, puede usar la secuencia de comandos a continuación para obtener un método estático y una instancia de método profundo.Si desea obtener métodos de la instancia creada, no olvide pasarla
constructor
.fuente
Creo que hay una razón histórica simple por la que no puede enumerar los métodos de objetos integrados como Array, por ejemplo. Este es el por qué:
Los métodos son propiedades del prototipo-objeto, digamos Object.prototype. Eso significa que todas las instancias de objetos heredarán esos métodos. Es por eso que puede usar esos métodos en cualquier objeto. Decir .toString () por ejemplo.
Entonces, los métodos IF eran enumerables, e iteraría sobre decir {a: 123} con: "for (teclee {a: 123}) {...}" ¿qué pasaría? ¿Cuántas veces se ejecutará ese bucle?
Se iteraría una vez para la clave única 'a' en nuestro ejemplo. PERO TAMBIÉN una vez por cada propiedad enumerable de Object.prototype. Entonces, si los métodos fueran enumerables (de manera predeterminada), cualquier ciclo sobre cualquier objeto también lo haría sobre todos sus métodos heredados.
fuente
Object.getOwnPropertyNames(Array.prototype)
por ejemplo