2016-12-04 37 views
8

Tôi muốn người dùng chỉ đặt thuộc tính cụ thể cho đối tượng nhưng đồng thời đối tượng đó phải được tạo từ lớp tùy chỉnh.Trả lại ES6 Proxy từ hàm tạo lớp ES6

Ví dụ

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

row có thể có phương pháp. Nhưng khi người dùng đang cố gắng đặt row.password, họ không được phép.

Một cách để thực hiện việc này là sử dụng new Proxy thay vì new Row nhưng sau đó chúng tôi sẽ loại bỏ tất cả những điều tuyệt vời mà chúng tôi đang thực hiện bên trong lớp . Tôi muốn new Row trả về đối tượng proxy với tham chiếu this làm mục tiêu của proxy.

Bất kỳ ai có ý tưởng về điều này? Nếu bạn biết mongoose, cách mongoose đang làm việc đó?

+2

Bạn có thể mô tả sự cố bạn đang cố giải quyết chi tiết hơn không? Dường như bạn đang mô tả một số giải pháp có thể (sử dụng proxy), nhưng không thực sự mô tả những gì bạn đang cố gắng thực hiện. – jfriend00

Trả lời

3

Bạn có thể thực hiện việc này mà không cần sử dụng Proxy.

Trong constructor lớp của bạn, bạn có thể xác định sở hữu mật khẩu như thế này:

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 
} 

Bạn có thể tìm thêm thông tin về làm thế nào để sử dụng này trên trang Object.defineProperty() của MDN.

+0

Mong muốn của tôi là cho phép các nhà điều hành thuộc tính Object và Array được quan sát. Điều này có nghĩa là tất cả các tên chưa biết. Việc trả lại Proxy trong hàm tạo sẽ làm cho nó có thể, xác định các thuộc tính theo tên không. –

5

Nếu proxy chắc chắn xảy ra với bạn, một giải pháp có thể có để giới hạn chức năng thiết lập là trả về phiên bản Proxy ES6.

Theo mặc định, hàm tạo trong javascript trả về this đối tượng tự động nhưng bạn có thể xác định và trả về hành vi tùy chỉnh bằng cách khởi tạo proxy trên this làm mục tiêu. Hãy nhớ rằng phương thức set trong proxy sẽ trả về một giá trị boolean.

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

Vì vậy, bây giờ bạn không được phép để thiết lập các thuộc tính phi setable theo proxy.

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

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

Cũng có thể có hành vi tùy chỉnh trên phương thức tải.

Lưu ý: Theo MDN vào lúc này, khả năng tương thích trình duyệt cho handler.set() là không rõ ràng được nêu ra. Tuy nhiên, nó hoạt động cho tôi trên Node v8.1.3

+0

Lỗi: "Mã thông báo không mong muốn mới" ?! Tôi không nghĩ rằng bạn có thể sử dụng 'mới' trong một nhà xây dựng, và nó cũng không giống như "trở lại Proxy"? –

+1

Có vẻ như nó đang hoạt động ?! Tốt đẹp. Có vẻ như các nhà xây dựng đã không trả lại Proxy mới trong các lần thử khác, vì vậy cảm ơn ví dụ này. –

+0

@MasterJames Đừng lo. Vâng, nó hoạt động với tôi trên Node v8.1.3. – hallaji