For … in not yielding methods

99封情书 提交于 2021-01-28 10:17:01

问题


Given the following:

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()

I run this with ts-node index.ts and all i get is:

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

With no reference to myMethod. I would like to iterate over all the methods of my class, but they don't appear to exist


回答1:


for..in iterates over all enumerable properties of the instance and up the prototype chain. But normal methods in a class are not enumerable:

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

So it doesn't get iterated over.

If you want to iterate over non-enumerable properties as well, use Object.getOwnPropertyNames (which iterates over the object's own property names, so you'll need to do so recursively if you want all property names anywhere in the prototype chain):

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();

You could also make the method enumerable:

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();

Or assign the method after the class definition:

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

Or assign it to the instance in the constructor:

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();


来源:https://stackoverflow.com/questions/64980276/for-in-not-yielding-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!