Iterate through methods and properties of an ES6 class

久未见 提交于 2020-01-23 06:28:53

问题


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

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