问题
So with the growth of new frameworks with JavaScript many have adopted ECMAScript 6 shim's or TypeScript, with many new features. My question is this:
How does one iterate over the methods/properties of an ES6 class?
e.g. (with objects)
var obj = {
prop: 'this is a property',
something: 256,
method: function() { console.log('you have invoked a method'); }
}
for (var key in obj) {
console.log(key);
}
// => 'prop'
// => 'something'
// => 'method'
(with classes)
class MyClass {
constructor() {
this.prop = 'prop';
this.something = 256;
}
method() {
console.log('you have invoked a method');
}
}
How do I list the methods MyClass has, and optionally its properties as well?
回答1:
The constructor and any defined methods are non-enumerable properties of the class's prototype object.
You can therefore get an array of the names (without constructing an instance of the class) with:
Object.getOwnPropertyNames(MyClass.prototype)
You cannot obtain the properties without creating an instance, but having done so you can use the Object.keys function which returns only the enumerable properties of an object:
Object.keys(myInstance)
AFAIK there's no standard way to obtain both the non-enumerable properties from the prototype and the enumerable properties of the instance together.
回答2:
There is a way to find the names of the methods only. The following has been tested in nodeJS v10.9.0 with no special flags.
First we inject a new method into Object.
Object.methods = function(klass) {
const properties = Object.getOwnPropertyNames(klass.prototype)
properties.push(...Object.getOwnPropertySymbols(klass.prototype))
return properties.filter(name => {
const descriptor = Object.getOwnPropertyDescriptor(klass.prototype, name)
if (!descriptor) return false
return 'function' == typeof descriptor.value && name != 'constructor'
})
}
You can see above that it is necessary to specifically exclude the constructor as it is not strictly a method of the class.
Create some class containing a constructor, accessors and methods
class Test {
constructor(x, y) {
this.x = x
this.y = y
}
sum() { return x + y }
distanceFromOrigin() { return Math.sqrt(this.squareX + this.squareY) }
get squareX() { return this.x * this.x }
get squareY() { return this.y * this.y }
[Symbol.iterator]() {
return null // TODO
}
}
Let's see how this works
> console.log(Object.methods(Test))
Array(3) ["sum", "distanceFromOrigin", Symbol(Symbol.iterator)]
回答3:
I've not tested, still I think that there are 2 ways to do it. 1st one is to return the 'this' enviroment and loop over it. 2nd one is the same as Javascript's object. Example for 1st one:- (untested)
class MyClass {
constructor() {
this.prop = 'prop';
this.something = 256;
}
method() {
console.log('you have invoked a method');
}
get getthis()
{
return this;
}
}
for( var key in MyClass.getthis )
{
console.log(key);
}
this is the second method:-( untested )
class MyClass {
constructor() {
this.prop = 'prop';
this.something = 256;
}
method() {
console.log('you have invoked a method');
}
}
for( var key in MyClass )
{
console.log(key);
}
来源:https://stackoverflow.com/questions/37771418/iterate-through-methods-and-properties-of-an-es6-class