如何正确地将其绑定到Javascript中的getter/setter
假设我有一个类,它将其实例的属性存储在嵌套对象中:如何正确地将其绑定到Javascript中的getter/setter,javascript,bind,getter-setter,defineproperty,Javascript,Bind,Getter Setter,Defineproperty,假设我有一个类,它将其实例的属性存储在嵌套对象中: this.Properties = { "Position":{ "X": 400, "Y": 100 }, "Colour": "#007fff7f" }; 我想为每个(嵌套的)属性定义特殊的getter/setter,这样我就可以添加范围检查/自动更新实例特定HTML元素的属性,等等。当我尝试使用普通方法时,我意
this.Properties = {
"Position":{
"X": 400,
"Y": 100
},
"Colour": "#007fff7f"
};
我想为每个(嵌套的)属性定义特殊的getter/setter,这样我就可以添加范围检查/自动更新实例特定HTML元素的属性,等等。当我尝试使用普通方法时,我意识到我无法将范围绑定到getter/setter中的参数:
//(based on https://stackoverflow.com/a/16400626)
//Define function prototype for binding an argument without overriding the old this:
Function.prototype.BindArgs = function(...boundArgs){
const targetFunction = this;
return function (...args) { return targetFunction.call(this, ...boundArgs, ...args); };
};
//...
{
get X(){
return this.__X__;
},
set X(Scope, Value){
this.__X__ = Value;
Scope.HTMLElement.style.left = Value + "px";
}.BindArgs(this) //This is incorrect syntax
}
上面的代码没有运行:不是因为BindArgs是一个无效的原型,而是因为。建议使用Object.defineProperty,它实际起作用:
Object.defineProperty(this.Properties.Position, "X", {
"get": function(){
return this.__X__;
}
"set": function(Scope, Value){
this.__X__ = Value;
Scope.HTMLElement.style.left = Value + "px";
}.BindArgs(this)
});
现在,当我有了一些像上面例子中那样的属性时,这将是很好的,但是必须对几十个属性执行这项操作变得非常乏味-尤其是对于嵌套属性有没有另一种更整洁的方法来定义自定义getter/setter并能够将参数绑定到它们?正常语法是理想的,因为它将全部位于对象定义内部,而不是像object.defineProperty那样分散。显而易见的答案是使用普通函数获取/设置值,但这样做意味着必须重构大量代码…我建议您使用。它只需要极少的代码更改,您可以一次性处理多个属性
let validator = {
set: function(obj, prop, value) {
//in any of these cases you can return false or throw an error to refuse the new value
switch(prop) {
case "X":
Scope.HTMLElement.style.left = value + "px";
break;
case "Y":
Scope.HTMLElement.style.top = value + "px";
break;
case "Colour":
Scope.HTMLElement.style.color = value;
}
obj[prop] = value;
return true;
}
};
this.Properties.Position = new Proxy(this.Properties.Position, validator);
this.Properties = new Proxy(this.Properties, validator);
请注意,这使用了一个快捷方式(对
属性和属性.位置都使用相同的验证器),如果发现属性名称重叠,则可能需要多个验证器
对象。太好了,非常感谢!遗憾的是,我仍然必须为每个嵌套对象定义它,但这比我的object.defineProperty更具可读性。这也意味着我不必使用自定义函数原型,因为它不会覆盖这一点,这很好@Permile很可能您可以编写一个简单的循环,为几行中的每个嵌套对象定义它。我不确定您需要验证的约束条件等。