ES6 Iterate over class methods

Dada essa class; Como eu iria iterar sobre os methods que inclui?

class Animal { constructor(type){ this.animalType = type; } getAnimalType(){ console.log('this.animalType: ', this.animalType ); } } let cat = window.cat = new Animal('cat') 

O que tentei foi o seguinte sem sucesso:

 for (var each in Object.getPrototypeOf(cat) ){ console.log(each); } 

Você pode usar Object.getOwnPropertyNames no protótipo:

 Object.getOwnPropertyNames( Animal.prototype ) // [ 'constructor', 'getAnimalType' ] 

Eu sei, eu sei, mas ei …

 const deepProps = x => x && x !== Object.prototype && Object.getOwnPropertyNames( x ).concat( deepProps( Object.getPrototypeOf( x ) ) || [] ); const deepFunctions = x => deepProps( x ).filter( name => typeof x[ name ] === "function" ); const userFunctions = x => new Set( deepFunctions( x ).filter( name => name !== "constructor" && !~name.indexOf( "__" ) ) ); 

uso:

 class YourObject { hello() { return "uk"; } goodbye() { return "eu"; } } class MyObject extends YourObject { hello() { return "ie"; } } const x = new MyObject(); userFunctions( x ); // [ "hello", "goodbye" ] 

Como os methods na class ES6 não são enumeráveis, você não tem outra opção a não ser usar Object.getOwnPropertyNames () para obter uma matriz de todas as suas propriedades.

Depois de conseguir isso, existem várias maneiras de extrair methods, o mais simples dos quais pode estar usando Array.prototype.forEach () .

Confira o seguinte trecho:

 Object.getOwnPropertyNames(Animal.prototype).forEach((value) => { console.log(value); }) 

verifique este violino

https://jsfiddle.net/ponmudi/tqmya6ok/1/

 class Animal { constructor(type){ this.animalType = type; } getAnimalType(){ console.log('this.animalType: ', this.animalType ); } } let cat = new Animal('cat'); //by instance document.getElementById('1').innerHTML = Object.getOwnPropertyNames(cat); //by getting prototype from instance document.getElementById('2').innerHTML = Object.getOwnPropertyNames(Object.getPrototypeOf(cat)); //by prototype document.getElementById('3').innerHTML = Object.getOwnPropertyNames(Animal.prototype); 

Se você precisar obter methods de superclass, também poderá chamar Object.getPrototypeOf() repetidamente até encontrá-los todos. Você provavelmente vai querer parar quando chegar ao Object.prototype , porque os methods lá são fundamentais e você geralmente não quer tocá-los com qualquer código que use reflection.

A questão Obter funções (methods) de uma class tem uma resposta que inclui uma function para fazer isso, mas tinha algumas deficiências (incluindo o uso de uma condição de loop que teve um efeito colateral de modificar um argumento de function, o que eu acho escolhas de estilo de código em uma única linha de código …), então eu o reescrevi aqui:

 export function listMethodNames (object, downToClass = Object) { // based on code by Muhammad Umer, https://stackoverflow.com/a/31055217/441899 let props = []; for (let obj = object; obj !== null && obj !== downToClass.prototype; obj = Object.getPrototypeOf(obj)) { props = props.concat(Object.getOwnPropertyNames(obj)); } return props.sort().filter((e, i, arr) => e != arr[i+1] && typeof object[e] == 'function'); } 

Além de corrigir o bug no código original (que não copiou o object em outra variável para o loop, então no momento em que foi usado para filtragem na linha de retorno ele não era mais válido) isso fornece um argumento opcional para Pare a iteração em uma class configurável. O padrão é Object (então os methods do Object são excluídos; se você quiser incluí-los, pode usar uma class que não aparece na cadeia de inheritance … talvez fazer uma class de marcador, por exemplo, class IncludeObjectMethods{} sentido). Também alterei o loop do para um loop for clear e reescrevi a function ... estilo antigo function ... filter em uma function de seta do ES6 para tornar o código mais compacto.

Para qualquer pessoa que esteja usando o tipo Datilografado interessado nesse tipo de pergunta, você pode fazer muitas coisas de maneira simples usando a API de reflection de metadados. Por exemplo, você pode adicionar metadados às suas aulas usando decoradores e obter informações sobre methods de class, propriedades e seus tipos. O typescript e seus tipos permitem fazer coisas parecidas com linguagens compiladas como java, c # e suas APIs de introspecção.

Dê uma olhada nesses links para mais informações:

https://www.typescriptlang.org/docs/handbook/decorators.html

https://www.npmjs.com/search?q=reflect-metadata