6

鉴于这两个类

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']

这是一个 Babel 示例


更新

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

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

class Bar extends Foo {

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

}

这是装饰器的来源:

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

这是一个 Babel 示例

4

2 回答 2

7

这不是在类中声明属性的有效语法。相反,在构造函数中声明它们。

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

然后你可以让他们使用Object.keys.

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

class Foo {
  f1 = 0;
  ...
}

至于访问 getter,getter 默认是不可枚举的,不能使用Object.keys或任何类似机制访问。但是,您可以使用Object.defineProperty.

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

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

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

function enumerable() {
  return function(target, key, descriptor) {
    if (descriptor) {
      descriptor.enumerable = true;
    }
  }
}
于 2016-01-07T20:22:04.577 回答
1

我觉得这个问题之前已经回答过了。您可以应用于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');
}
于 2016-01-08T01:39:29.740 回答