Você pode usar Object.getOwnPropertyNames()
para obter todas as propriedades que pertencem a um objeto, sejam enumeráveis ou não. Por exemplo:
console.log(Object.getOwnPropertyNames(Math));
//-> ["E", "LN10", "LN2", "LOG2E", "LOG10E", "PI", ...etc ]
Você pode usar filter()
para obter apenas os métodos:
console.log(Object.getOwnPropertyNames(Math).filter(function (p) {
return typeof Math[p] === 'function';
}));
//-> ["random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", ...etc ]
Nos navegadores ES3 (IE 8 e inferiores), as propriedades dos objetos internos não são enumeráveis. Objetos como window
e document
não são incorporados, são definidos pelo navegador e provavelmente enumeráveis pelo design.
Do ECMA-262 Edição 3 :
Objeto global
Há um objeto global exclusivo (15.1), criado antes do controle entrar em qualquer contexto de execução. Inicialmente, o objeto global possui as seguintes propriedades:
• Objetos internos, como Math, String, Date, parseInt, etc. Estes possuem atributos {DontEnum} .
• Propriedades adicionais definidas pelo host. Isso pode incluir uma propriedade cujo valor é o próprio objeto global; por exemplo, no modelo de objeto de documento HTML, a propriedade window do objeto global é o próprio objeto global.
À medida que o controle entra nos contextos de execução e quando o código ECMAScript é executado, propriedades adicionais podem ser adicionadas ao objeto global e as propriedades iniciais podem ser alteradas.
Devo salientar que isso significa que esses objetos não são propriedades enumeráveis do objeto Global. Se você examinar o restante do documento de especificação, verá que a maioria das propriedades e métodos internos desses objetos têm o { DontEnum }
atributo definido neles.
Atualização: um colega usuário do SO, CMS, trouxe um bug do IE referente{ DontEnum }
à minha atenção.
Em vez de verificar o atributo DontEnum, o JScript da [Microsoft] pulará qualquer propriedade em qualquer objeto em que haja uma propriedade com o mesmo nome na cadeia de protótipos do objeto que possui o atributo DontEnum.
Em resumo, tenha cuidado ao nomear as propriedades do seu objeto. Se houver uma propriedade ou método de protótipo interno com o mesmo nome, o IE o ignorará ao usar um for...in
loop.
Object.getOwnPropertyNames()
, que retornará propriedades e métodos não enumeráveis.Object.getOwnPropertyNames(Array.prototype)
?Não é possível no ES3, pois as propriedades possuem um
DontEnum
atributo interno que nos impede de enumerar essas propriedades. O ES5, por outro lado, fornece descritores de propriedades para controlar os recursos de enumeração de propriedades, para que propriedades nativas e definidas pelo usuário possam usar a mesma interface e desfrutar dos mesmos recursos, o que inclui a capacidade de ver propriedades não enumeráveis programaticamente.A
getOwnPropertyNames
função pode ser usada para enumerar todas as propriedades do objeto passado, incluindo aquelas que não são enumeráveis. Em seguida, umatypeof
verificação simples pode ser empregada para filtrar as não funções. Infelizmente, o Chrome é o único navegador em que ele trabalha atualmente.logs
["cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"]
em nenhuma ordem específica.fonte
Dessa forma, você obterá todos os métodos que você pode chamar
obj
. Isso inclui os métodos que "herda" de seu protótipo (comogetMethods()
em java). Se você quiser apenas ver os métodos definidos diretamente porobj
você, verifique comhasOwnProperty
:fonte
document
ouwindow
tenho mais sorte. Francamente, é um pouco inesperado, eu não sei por que ele não funciona para Math etc.document
ewindow
são objetos com propriedades enumeráveis fornecidas pelo navegador, eles não fazem parte do tempo de execução do script. Objetos nativos são e obviamente as propriedades não são enumeráveis.O suporte ao navegador mais moderno
console.dir(obj)
, que retornará todas as propriedades de um objeto que ele herdou por meio de seu construtor. Consulte a documentação do Mozilla para obter mais informações e suporte atual ao navegador.fonte
As outras respostas aqui funcionam para algo como Math, que é um objeto estático. Mas eles não funcionam para uma instância de um objeto, como uma data. Eu encontrei o seguinte para trabalhar:
https://jsfiddle.net/3xrsead0/
Isso não funcionará para algo como a pergunta original (matemática); portanto, escolha sua solução com base nas suas necessidades. Estou postando isso aqui porque o Google me enviou a essa pergunta, mas eu queria saber como fazer isso para instâncias de objetos.
fonte
A resposta curta é que você não pode, porque
Math
eDate
(em cima da minha cabeça, tenho certeza que existem outros) não são objetos normais. Para ver isso, crie um script de teste simples:Você vê que ele apresenta como um objeto da mesma maneira que o documento em geral, mas quando você realmente tenta ver nesse objeto, vê que é código nativo e algo não exposto da mesma maneira para enumeração.
fonte
Math
tem um método estático onde você pode chamar diretamente likeMath.abs()
enquantoDate
tem um método estáticoDate.now()
e também um método de instância em que é necessário criar uma nova instância primeirovar time = new Date()
para chamartime.getHours()
.É claro que você precisará filtrar as chaves obtidas para o método estático para obter nomes de métodos reais, porque você também pode obter
length, name
que não sejam uma função na lista.Mas como se queremos obter todo método disponível da classe que estende outra classe?
Claro que você precisará escanear a raiz do protótipo como usar
__proto__
. Para economizar seu tempo, você pode usar o script abaixo para obter o método estático e a instância profunda do método.Se você deseja obter métodos da instância criada, não esqueça de passar a instância
constructor
.fonte
Acredito que há uma simples razão histórica pela qual você não pode enumerar métodos de objetos internos, como Array, por exemplo. Aqui está o porquê:
Métodos são propriedades do objeto-protótipo, como Object.prototype. Isso significa que todas as instâncias de objetos herdarão esses métodos. É por isso que você pode usar esses métodos em qualquer objeto. Diga .toString (), por exemplo.
Portanto, se os métodos fossem enumeráveis e eu repetiria digitando {a: 123} com: "for (digite {a: 123}) {...}" o que aconteceria? Quantas vezes esse loop seria executado?
Seria iterado uma vez para a chave única 'a' em nosso exemplo. MAS TAMBÉM uma vez para cada propriedade enumerável de Object.prototype. Portanto, se os métodos fossem enumeráveis (por padrão), qualquer loop sobre qualquer objeto também repetiria todos os seus métodos herdados.
fonte
Object.getOwnPropertyNames(Array.prototype)
, por exemplo