我希望用户只为对象设置特定属性,但同时应该从自定义类构造该对象。
例如
var row = new Row({
name : 'John Doe',
email : 'uhiwarale@gmail.com'
}, Schema);
row
可以有方法。但是当用户试图设置时 row.password
,他们是不允许的。
一种方法是使用 new Proxy
代替 new Row
但是我们将放弃我们正在做的所有酷事 Row
类。我想要 new Row
返回一个代理对象 this
引用作为代理的目标。
有人对此有什么想法吗?如果你知道的话 mongoose
, 怎么样 mongoose
这样做?
如果确定代理发生了,则限制集合功能的一种可能解决方案是返回ES6代理实例。
默认情况下,javascript中的构造函数返回 this
自动对象,但您可以通过实例化代理来定义和返回自定义行为 this
作为目标。请记住,代理中的set方法应返回一个布尔值。
MDN:set方法应该返回一个布尔值。返回true表示
这项任务成功了。如果set方法返回false,那么
赋值发生在严格模式代码中,将抛出TypeError。
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();
}
}
因此,现在不允许根据代理设置非setable属性。
let row = new Row({
name : 'John Doe',
email : 'john@doe.com'
}, Schema);
row.password = 'blahblahblah'; // Error: Cannot set the password property
也可以在get方法上使用自定义行为。
但是,请注意并注意覆盖返回到调用上下文的引用。
注意: 示例代码已在Node v8.1.3上进行了测试
您可以在不使用Proxies的情况下执行此操作。
在类构造函数中,您可以像这样定义password属性:
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()
页。