如何迭代ES6 / 2015类实例的属性

时间:2016-01-07 20:19:07

标签: javascript ecmascript-next

给出这两个类

class Foo{
  f1;

  get f2(){
    return "a";
  }
}

class Bar extends Foo {
  b1;

  get b2(){
    return "a";
  }
}

let bar = new Bar();

什么代码会从bar实例中获取此属性列表? ['f1', 'f2', 'b1', 'b2']

Here is a Babel sample

更新

这应该是@Marc C答案的一部分:

使用装饰器我可以轻松地将不可枚举的属性转换为可枚举的属性:

class Bar extends Foo {

  @enumerable()  
  get b2(){
    return "a";
  }

}

这是装饰者来源:

function enumerable() {
  return function(target, key, descriptor) {
    if (descriptor) {
      descriptor.enumerable = true;
    }
  };
}

Here is a Babel sample

2 个答案:

答案 0 :(得分:6)

在课堂上不是valid syntax for declaring properties。相反,在构造函数中声明它们。

class Foo {
  constructor() {
    this.f1 = undefined;
  }
}

然后你可以使用Object.keys来获取它们。

使用Babel中的实验性功能将允许您使用该语法声明属性,但必须声明它们的值。

class Foo {
  f1 = 0;
  ...
}

对于访问getter,getter在默认情况下是不可枚举的,无法使用Object.keys或任何类似的机制访问。但是,您可以使用Object.defineProperty创建可枚举的getter。

Object.defineProperty(bar, 'f2', {
  get() { 
    return "a"; 
  }
});

如果您正在使用实验性ES7功能,则可以将decorator应用于类方法并获得相同的行为。请参阅此Babel sample

class Foo {
  @enumerable()
  get b2() {
    return "a";
  }
}

function enumerable() {
  return function(target, key, descriptor) {
    if (descriptor) {
      descriptor.enumerable = true;
    }
  }
}

答案 1 :(得分:0)

我觉得之前已经回答了这个问题。您可以将Object.getOwnPropertyNames应用于实例及其原型:

function getAllPropertyNames(obj) {
  let names = [];
  do {
    names.push.apply(names, Object.getOwnPropertyNames(obj));
    obj = Object.getPrototypeOf(obj);
  } while(obj !== Object.prototype);
  return names.filter(name => name !== 'constructor');
}
相关问题