2016-01-07 6 views
5

gegeben diese beiden KlassenWie iterieren Eigenschaften einer ES6/2015 Klasseninstanz

class Foo{ 
    f1; 

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

class Bar extends Foo { 
    b1; 

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

let bar = new Bar(); 

Welcher Code wird mir diese Liste von Eigenschaften aus der bar Instanz bekommen? ['f1', 'f2', 'b1', 'b2']

Here is a Babel sample


aktualisiert

Dies sollte Teil der @Marc C Antwort sein:

einen Dekorateur verwendet ich leicht eine nicht zählbare Eigenschaft in eine zählbare Eigenschaft drehen kann:

class Bar extends Foo { 

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

} 

Hier ist der Dekorateur Quelle:

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

Here is a Babel sample

+0

Dies scheint ehrlich wie ein dup von http://stackoverflow.com/questions/31054910/get-functions-of-a-class. Es gibt keinen Grund, die Eigenschaften aufzählbar zu machen. – loganfsmyth

+1

[tag: babel]: * "Python Internationalisierungs-Bibliothek mit einem Schwerpunkt auf Web-basierte Anwendungen. Für Fragen über die JavaScript-Bibliothek verwenden Sie bitte [Babeljs]." * –

Antwort

5

Das ist nicht valid syntax for declaring properties in einer Klasse ist. Deklarieren Sie sie stattdessen im Konstruktor.

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

Dann können Sie sie mit Object.keys erhalten.

Mit experimentellen Features in Babel können Sie Eigenschaften mit dieser Syntax deklarieren, aber ihre Werte müssen deklariert werden.

class Foo { 
    f1 = 0; 
    ... 
} 

wie für die Getter Zugriff Getter ist nicht-enumerable standardmäßig und nicht zugegriffen werden kann Object.keys oder ähnlichen Mechanismus. Sie können jedoch aufzählbare Getter mithilfe von Object.defineProperty erstellen.

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

Wenn Sie experimentelle ES7 Funktionen verwenden sind, können Sie eine decorator auf die Klassenmethode anwenden und das gleiche Verhalten bekommen. Siehe hierzu Babel sample.

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

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

1 - Ich verwende diese experimentelle Funktion, die Babel unterstützt (z 'f1' und' b1'). 2 - 'Object.keys()' bringt mich nicht 'b2' und' f2'. – Sylvain

+0

@Sylvain Babel kann es akzeptieren, aber wenn Sie sich den kompilierten Code ansehen, werden 'f1' und' b1' nicht deklariert. Babel deklariert sie, wenn Sie ihnen Werte wie "f1 = 0" zuweisen. Wie für 'f2' und' b2' sind [getters standardmäßig nicht aufzählbar] (http://stackoverflow.com/questions/34517538/setting-an-es6-class-getter-to-enumerable). –

+0

guter Punkt. 1 - Ich kann das reparieren (und es außerhalb eines Konstruktors belassen), wenn ich sie oben auf undefiniert setze. 2 - Gibt es eine Funktion, die mir die Liste dieser Getter bringt oder sind sie wirklich versteckt? – Sylvain

0

Ich fühle mich wie dies zuvor beantwortet wurde. Sie können Object.getOwnPropertyNames auf die Instanz und ihre Prototypen gelten:

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