根据MDN,
handler.set()
可以捕获Inherited属性赋值:
Object.create(proxy)[foo] = bar;
在这种情况下,如何监视并允许继承对象的本地分配?
var base = {
foo: function(){
return "foo";
}
}
var proxy = new Proxy(base, {
set: function(target, property, value, receiver){
console.log("called: " + property + " = " + value, "on", receiver);
//receiver[property] = value; //Infinite loop!?!?!?!?!
//target[property] = value // This is incorrect -> it will set the property on base.
/*
Fill in code here.
*/
return true;
}
})
var inherited = {}
Object.setPrototypeOf(inherited, Object.create(proxy));
inherited.bar = function(){
return "bar";
}
//Test cases
console.log(base.foo); //function foo
console.log(base.bar); //undefined
console.log(inherited.hasOwnProperty("bar")) //true

答案 0 :(得分:3)
经过一些额外的考虑,我注意到它拦截了3个操作:
属性赋值:proxy [foo] = bar和proxy.foo = bar 继承属性赋值:Object.create(proxy)[foo] = bar
Reflect.set()
但不是Object.defineProperty()
,它似乎比=运算符更低。
因此以下工作:
var base = {
foo: function(){
return "foo";
}
};
var proxy = new Proxy(base, {
set: function(target, property, value, receiver){
var p = Object.getPrototypeOf(receiver);
Object.defineProperty(receiver, property, { value: value }); // ***
return true;
}
});
var inherited = {};
Object.setPrototypeOf(inherited, Object.create(proxy));
inherited.bar = function(){
return "bar";
};
// Test cases
console.log(base.foo); // function foo
console.log(base.bar); // undefined
console.log(inherited.bar); // function bar
console.log(inherited.hasOwnProperty("bar")) // true

答案 1 :(得分:1)
我看到两个选项(可能):
将属性存储在Map
中,使接收方键入的Map
中的各种接收器的WeakMap
保持不变。通过检查get
并在那里返回映射而不是从对象返回来满足Map
。 (还有has
。)轻微的问题是你还需要代理接收器(而不仅仅是base
)才能处理ownKeys
。所以这可能是行不通的。
设置时暂时将代理从继承链中取出。
这是第二个:
var base = {
foo: function(){
return "foo";
}
};
var proxy = new Proxy(base, {
set: function(target, property, value, receiver){
const p = Object.getPrototypeOf(receiver); // ***
Object.setPrototypeOf(receiver, null); // ***
receiver[property] = value; // ***
Object.setPrototypeOf(receiver, p); // ***
return true;
}
});
var inherited = {};
Object.setPrototypeOf(inherited, Object.create(proxy));
inherited.bar = function(){
return "bar";
};
// Test cases
console.log("base.foo:", base.foo); // function foo
console.log("base.bar:", base.bar); // undefined
console.log("inherited.bar:", inherited.bar); // function bar
console.log("inherited has own bar?", inherited.hasOwnProperty("bar")); // true