2015-12-29 23 views
18

ゲッタープロパティを持つES6クラス(babeljsでトランスコンパイル)があります。私はこれらのプロパティがデフォルトで列挙できないことを理解しています。私がいない個々のpersonに、プロトタイプ上で定義されているObject.definePropertyES6クラスのゲッターを列挙可能に設定する

// Declare class 
class Person { 
    constructor(myName) { 
    this.name = myName; 
    } 

    get greeting() { 
    return `Hello, I'm ${this.name}`; 
    } 
} 

// Make enumerable (doesn't work) 
Object.defineProperty(Person, 'greeting', {enumerable: true}); 

// Create an instance and get enumerable properties 
var person = new Person('Billy'); 
var enumerableProperties = Object.keys(person); 
// => ['name'] 

Plunker Example

+0

プロトタイプオブジェクトで定義します。 'Object.defineProperty(Person.prototype、...)' – Louy

+0

@Louyあなたの提案と同じプランナー - 変更なし:http://plnkr.co/edit/QkQ1JbFEjAAOIFPCtPk7?p=preview – lightswitch05

答えて

26

ES6スタイルゲッターを使用して列挙プロパティを作成することはできませんよ、なぜしかし、私は理解していません。列挙しgreetingプロパティを設定するには、変更する必要があります。

// Make enumerable (doesn't work) 
Object.defineProperty(Person, 'greeting', {enumerable: true}); 

へ:プロトタイプのプロパティが返されていないので、自身列挙プロパティをオブジェクト

// Make enumerable 
Object.defineProperty(Person.prototype, 'greeting', {enumerable: true}); 

Object.keysのみを返します。 greetingプロパティはObject.keys(Object.getPrototypeOf(person))、またはfor...inループにあります。 Updated Plunker

代わりに、あなたは人の個々のインスタンスはgreeting独自のを持ちたい場合は、コンストラクタでそれを定義することができます。

class Person { 
    constructor(myName) { 
    this.name = myName; 

    Object.defineProperty(this, 'greeting', { 
     enumerable: true, 
     get: function () { return `Hello, I'm ${this.name}`; } 
    }); 
    } 
} 

Updated Plunker

+1

これはうまく動作しますが、直感的ではありません。論理的にも – lightswitch05

+0

'Object.getOwnPropertyDescriptor(Person.prototype、 'greeting')'から返された記述子を使用する必要があります。そうでなければ、 'greeting'デスクリプタを拡張するのではなく、' get'ビヘイビアを失います。 –

+3

@SeanVieiraいいえ、必要はありません。 'defineProperty'を使うと、既存のプロパティーを変更/設定することもできます。 'value'や新しい' get'を指定しない限り、enumerableを設定しても古い 'get'は動作しません。 (私の答えでは 'person [name]'が挨拶を正しく返していることを、最初のプランナーで通知しました)。 – Paulpro

0

あなたはこのようにトリックを行うことがあります。

class Person { 
    static createFields({ name }) { 
    return { 
     name, 
     get greeting() { 
     return `Hello, I'm ${this.name}`; 
     } 
    } 
    } 

    constructor(...args) { 
    const inst = this.constructor.createFields(...args) 
    const desc = Object.getOwnPropertyDescriptors(inst) 
    Object.defineProperties(this, desc) 
    return this 
    } 
} 

メリット単純なオブジェクトのゲッターは、デフォルトでは列挙可能で、設定可能ですが、c毎回これらの修飾子についてです。

しかし、これはちょっと変わっています。実際に使用する必要があるかどうかは不明です。

関連する問題