最初,我的目标是设置类OnlyOneProp的实例的任何属性,
obj.what_ever_property = "value"
最后只会修改obj.the_only_prop

行为是这样的:

var obj = new OnlyOneProp();
obj.what_ever_property = "value";
console.log(obj.only_property, obj.what_ever_property);
// expected output:
// >value undefined


原始问题:有没有办法实现上述行为?





编辑:

关于solution in the answer
以下是一些后续问题:

1)以上代码是否有重大缺陷? (就像我曾经混淆了receivertarget一样,这可能会在设置器上造成无限循环)

2)Proxy是否会严重阻碍性能?

3)有什么方法可以绕过上述代理设置器? (就像defineProperty()一样)

4)也可以是ReadOnlyObject的实现(在setter中删除设置行之后),但是会有更好的实现吗? (这有点不合时宜,但我也想知道,因为我真的想删除仅覆盖构造函数的顶级Proxy)

最佳答案

如果从构造函数返回对象,则new运算符将返回该对象,而不是作为this传递给构造函数的新对象。所以OnePropertyClass的更直接的版本可能是

class OnePropertyClass{
    constructor( value) {
        var self = this;
        return new Proxy( this, {
           set: function(target, property, value) {
                    self["only_property"] = value;
                    return true;
                }
           }
        );
    }
}


这可以通过使用箭头函数而不是闭包来简化:



class OnePropertyClass{
    constructor() {
        return new Proxy( this, {
           set: (target, property, value) => {
                    this.only_property = value;
                    return true;
                }
           }
        );
    }
}

var obj = new OnePropertyClass();
obj.what_ever_property = "value";
console.log(obj.only_property, obj.what_ever_property);





它不会设置任何setter循环,因为setter将值存储在构造函数的实际this对象上,而不是存储在返回的代理对象上。

此版本的OnePropertyClass实例通常照常继承-constructor属性返回OnePropertyClass构造函数,而Object.prototype属性和方法仍被继承。

您可能希望冻结OnePropertyClass.prototype以防止添加任何其他继承的属性。您可能还希望为defineProperty以及可能为setPrototype提供陷阱功能,以防止添加运行时属性-有关详细信息,请参见MDN handler object methods

代理的实现可能是用C ++编写的,我希望大多数额外的开销将在于调用setter函数。

我尚未测试此版本的可扩展性,并且未使用target处理程序的set参数请在使用前进行实验:-)

10-06 04:41