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

Javascript 如何迭代ES6/2015类实例的属性,javascript,ecmascript-next,Javascript,Ecmascript Next,鉴于这两类 class Foo{ f1; get f2(){ return "a"; } } class Bar extends Foo { b1; get b2(){ return "a"; } } let bar = new Bar(); 什么代码可以从栏实例中获取此属性列表['f1','f2','b1','b2'] 更新 这应该是@Marc C答案的一部分: 使用装饰器,我可以轻松地将不可枚举属性转换为可枚举属性: class Bar

鉴于这两类

class Foo{
  f1;

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

class Bar extends Foo {
  b1;

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

let bar = new Bar();
什么代码可以从
实例中获取此属性列表<代码>['f1','f2','b1','b2']


更新

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

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

class Bar extends Foo {

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

}
以下是decorator源代码:

function enumerable() {
  return function(target, key, descriptor) {
    if (descriptor) {
      descriptor.enumerable = true;
    }
  };
}
那不是在课堂上。相反,在构造函数中声明它们

class Foo {
  constructor() {
    this.f1 = undefined;
  }
}
然后您可以使用
Object.keys
获取它们

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

class Foo {
  f1 = 0;
  ...
}
至于访问getter,默认情况下getter是不可枚举的,不能使用
Object.keys
或任何类似机制访问。但是,可以使用创建可枚举的getter

如果您使用的是实验性的ES7特性,那么您可以对类方法应用a,并获得相同的行为。看这个


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

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');
}

1-我确实使用了babel支持的这个实验性功能(用于
f1
b1
)。2-
Object.keys()
无法获取
b2
f2
@Sylvain Babel可能会接受它,但如果查看编译后的代码,
f1
b1
不会被声明。如果您给它们赋值,例如
f1=0
,Babel将声明它们。至于
f2
b2
,很好。1-如果我将它们设置为未定义,我可以修复这个问题(并将其保留在构造函数之外)。2-是否有一个函数可以获取这些getter的列表,或者它们是真正隐藏的?@Sylvain以这种格式编写时,它们是真正隐藏的。使用
Object.defineProperty
,您可以创建一个可枚举的getter,并且该getter将是可见的。检查我上面的更新,如果您认为这是一个好主意,请将其添加到您的答案中,我将接受它(我不敢更新您的编辑您的答案)。老实说,这看起来像是重复。没有理由使属性可枚举:“Python国际化库侧重于基于web的应用程序。有关JavaScript库的问题,请使用[babeljs]”
class Foo {
  @enumerable()
  get b2() {
    return "a";
  }
}

function enumerable() {
  return function(target, key, descriptor) {
    if (descriptor) {
      descriptor.enumerable = true;
    }
  }
}
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');
}