【问题标题】:How to iterate over properties of an ES6/2015 class instance如何迭代 ES6/2015 类实例的属性
【发布时间】:2016-01-07 20:19:06
【问题描述】:

给定这两个类

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

【问题讨论】:

标签: javascript ecmascript-next


【解决方案1】:

那不是课堂上的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 - 我确实使用了 babel 支持的这个实验性功能(对于 f1b1)。 2 - Object.keys() 没有得到我 b2f2
  • @Sylvain Babel 可能会接受它,但如果您查看编译后的代码,f1b1 并未声明。如果您为它们分配诸如f1 = 0 之类的值,Babel 将声明它们。至于f2b2getters are not enumerable by default
  • 好点。 1 - 如果我将它们设置为未定义,我可以解决这个问题(并将其留在构造函数之外)。 2 - 是否有一个函数可以让我获得这些 getter 的列表,或者它们是否真的被隐藏了?
  • @Sylvain 当以这种格式编写时,它们是真正隐藏的。使用Object.defineProperty,您可以创建一个可枚举的getter,并且它是可见的。
  • 查看我上面的更新,如果您认为这是个好主意,请将其添加到您的答案中,我会接受(我不敢更新您的编辑您的答案)
【解决方案2】:

我觉得以前有人回答过这个问题。您可以将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');
}

【讨论】:

  • 这是让我走上正轨的唯一答案: var that = Object.getPrototypeOf(this); var props = Object.getOwnPropertyNames(that);只是......哇什么是语言js:-O
猜你喜欢
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多