Pour… en ne donnant pas de méthodes

Nov 23 2020

Compte tenu de ce qui suit:

export class MyClass {
    public dataA = 0
    private dataB = 123
    public myMethod(): any {
        return {
            test: 'true'
        }
    }

    constructor() {
        for (const propOrMethod in this) {
            console.log({propOrMethod})
        }
    }
}

const myInst = new MyClass()

Je lance ça avec ts-node index.tset tout ce que j'obtiens c'est:

{ propOrMethod: 'dataA' }
{ propOrMethod: 'dataB' }

Sans référence à myMethod. Je voudrais parcourir toutes les méthodes de ma classe, mais elles ne semblent pas exister

Réponses

2 CertainPerformance Nov 24 2020 at 04:37

for..initère sur toutes les propriétés énumérables de l'instance et dans la chaîne de prototypes. Mais les méthodes normales d'une classe ne sont pas énumérables:

class MyClass {
    myMethod() {
        return {
            test: 'true'
        };
    }
}
console.log(Object.getOwnPropertyDescriptor(MyClass.prototype, 'myMethod').enumerable);

Donc, cela ne se répète pas.

Si vous souhaitez également parcourir des propriétés non énumérables, utilisez Object.getOwnPropertyNames(qui itère sur les propres noms de propriété de l'objet , vous devrez donc le faire de manière récursive si vous voulez que tous les noms de propriétés n'importe où dans la chaîne de prototypes):

const recurseLog = obj => {
  for (const name of Object.getOwnPropertyNames(obj)) {
    console.log(name);
  }
  const proto = Object.getPrototypeOf(obj);
  if (proto !== Object.prototype) recurseLog(proto);
};
class MyClass {
    dataA = 0;
    dataB = 123;
    constructor() {
        recurseLog(this);
    }
    myMethod() {
        return {
            test: 'true'
        };
    }
}
const myInst = new MyClass();

Vous pouvez également rendre la méthode énumérable:

class MyClass {
    dataA = 0;
    dataB = 123;
    constructor() {
         for (const propOrMethod in this) {
            console.log({propOrMethod})
        }
    }
    myMethod() {
        return {
            test: 'true'
        };
    }
}
Object.defineProperty(MyClass.prototype, 'myMethod', { enumerable: true, value: MyClass.prototype.myMethod });
const myInst = new MyClass();

Ou attribuez la méthode après la définition de classe:

class MyClass {
    dataA = 0;
    dataB = 123;
    constructor() {
         for (const propOrMethod in this) {
            console.log({propOrMethod})
        }
    }
}
MyClass.prototype.myMethod = () => ({ test: 'true' });
const myInst = new MyClass();

Ou attribuez-le à l'instance dans le constructeur:

class MyClass {
    dataA = 0;
    dataB = 123;
    constructor() {
        this.myMethod = this.myMethod;
         for (const propOrMethod in this) {
            console.log({propOrMethod})
        }
    }
     myMethod() {
        return {
            test: 'true'
        };
    }
}
const myInst = new MyClass();