2016-12-04 9 views
8

ユーザはオブジェクトに特定のプロパティを設定するだけで、オブジェクトはカスタムクラスから構築する必要があります。ES6クラスコンストラクタからのES6プロキシの返却

var row = new Row({ 
    name : 'John Doe', 
    email : '[email protected]' 
}, Schema); 

row例えば

メソッドを有することができます。しかし、ユーザーがrow.passwordを設定しようとしているときは許可されません。

new Rowの代わりにを使用する方法もありますが、私たちはクラス内のすべてのクールなものを緩和します。私はnew Rowがプロキシのターゲットとしてthis参照とプロキシオブジェクトを返すようにします。

誰もがこれに関するアイデアを持っていますか? mongooseが分かっている場合、mongooseはそれをどうやって行っていますか?

+2

あなたが解決しようとしている問題についてもっと詳しく説明できますか?あなたは、(プロキシを使って)いくつかの可能な解決策を説明しているようですが、あなたが達成しようとしていることを本当に記述していません。 – jfriend00

答えて

3

これは、プロキシをまったく使用せずに行うことができます。あなたのクラスのコンストラクタで

あなたは、このように、パスワードのプロパティを定義することができます。

constructor(options, schema) { 
    this.name = options.name; 
    this.email = options.email; 
    Object.defineProperty(this, 'password', { 
     configurable: false, // no re-configuring this.password 
     enumerable: true, // this.password should show up in Object.keys(this) 
     value: options.password, // set the value to options.password 
     writable: false // no changing the value with this.password = ... 
    }); 
    // whatever else you want to do with the Schema 
} 

あなたはMDNのObject.defineProperty()ページにこれを使用する方法の詳細情報を見つけることができます。

+0

私の望みは、オブジェクトと配列のプロパティ演算子を観察できるようにすることです。これは不明な名前のすべてを意味します。コンストラクタでプロキシを返すことで、名前でプロパティを定義することはできません。 –

5

プロキシが確実に発生する場合、設定された機能を制限する1つの解決策は、ES6プロキシインスタンスを返すことです。

デフォルトでは、javascriptのコンストラクタはthisオブジェクトを自動的に返しますが、thisのプロキシをターゲットとしてインスタンス化することで、カスタム動作を定義して返すことができます。プロキシのsetメソッドはブール値を返す必要があることに注意してください。

MDN : The set method should return a boolean value. Return true to indicate that assignment succeeded. If the set method returns false, and the assignment happened in strict-mode code, a TypeError will be thrown.

class Row { 
    constructor(entry, schema) { 
    // some stuff 

    return new Proxy(this, { 
     set(target, name, value) { 
     let setables = ['name', 'email']; 
     if (!setables.includes(name)) { 
      throw new Error(`Cannot set the ${name} property`); 
     } else { 
      target[name] = value; 
      return true; 
     } 
     } 
    }); 
    } 

    get name() { 
    return this._name; 
    } 
    set name(name) { 
    this._name = name.trim(); 
    } 
    get email() { 
    return this._email; 
    } 
    set name(email) { 
    this._email = email.trim(); 
    } 
} 

だから、今、あなたは、プロキシによる非設定可能なプロパティを設定することはできません。

let row = new Row({ 
    name : 'John Doe', 
    email : '[email protected]' 
}, Schema); 

row.password = 'blahblahblah'; // Error: Cannot set the password property 

getメソッドでもカスタム動作が可能です。

注:現時点でMDNによると、handler.set()用ブラウザの互換性はまだ明らかにされていません。しかし、それはノードv8.1.3で私のために働きます

+0

エラー:「新しいトークンが予期しない」?私はコンストラクタで 'new'を使うことはできないと思うし、 "return proxy"も好きではない? –

+1

これは動作しているように見えますか?ニース。それはコンストラクタが他の試行で新しいProxyを返さなかったようです、この例のおかげで。 –

+0

@ MasterJames心配する必要はありません。うん、それはノードv8.1.3で私のために働く。 – hallaji