2016-01-07 24 views
5

的性质给出这两个类如何遍历一个ES6/2015类实例

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'S部分答案:

使用装饰我可以轻松地将非枚举属性为枚举属性:

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

+0

老实说,这似乎是http://stackoverflow.com/questions/31054910/get-functions-of-a-class的DUP。没有理由使这些属性可枚举。 – loganfsmyth

+1

[tag:babel]:*“Python国际化库,强调基于Web的应用程序。关于JavaScript库的问题,请使用[babeljs]。”* –

回答

5

这不是valid syntax for declaring properties的一类。相反,在构造函数中声明它们。

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

然后你可以使用Object.keys得到它们。

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

class Foo { 
    f1 = 0; 
    ... 
} 

作为用于访问吸气剂,吸气剂是由默认的非枚举,不能使用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; 
    } 
    } 
} 
+0

1 - 我使用babel支持的这个实验性功能'f1'和'b1')。 2 - 'Object.keys()'不会让我'b2'和'f2'。 – Sylvain

+0

@Sylvain Babel可能会接受它,但如果您查看编译后的代码,则不会声明“f1”和“b1”。如果你给它们赋值如'f1 = 0',Babel会声明它们。至于'f2'和'b2',[getters默认情况下是不可枚举的](http://stackoverflow.com/questions/34517538/setting-an-es6-class-getter-to-enumerable)。 –

+0

好点。 1 - 如果我将它们设置为undefined,我可以修复此问题(并将其保留在构造函数之外)。 2 - 是否有一个函数可以让我获得这些getter的列表,还是他们真的隐藏了? – Sylvain

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