2016-12-04 62 views
8

我希望用戶只爲對象設置特定的屬性,但同時該對象應該從自定義類構建。從ES6類構造函數中返回ES6代理

例如

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

row可以具有方法。但是當用戶試圖設置row.password時,他們是不允許的。

這樣做的一種方法是使用new Proxy而不是new Row,但是我們會在類中放鬆所有我們正在做的很酷的事情。我想new Row返回代理對象與this引用作爲代理的目標。

有人有什麼想法嗎?如果您知道mongoosemongoose是怎麼做到的?

+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

如果代理肯定會發生,那麼限制設置功能的一種可能的解決方案是返回一個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()瀏覽器的兼容性不是很明顯呢。然而它適用於Node v8.1.3

+0

錯誤:「意外的令牌新」?我不認爲你可以在構造函數中使用'new',它也不喜歡「return Proxy」? –

+1

哇,它看起來像這個工作?!尼斯。似乎構造函數沒有在其他嘗試中返回新的代理,所以感謝這個例子。 –

+0

@MasterJames不用擔心。是的,它在Node v8.1.3上適用於我。 – hallaji