Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么这个setter在我代理它时不给我截取的值?_Javascript_Es6 Proxy - Fatal编程技术网

Javascript 为什么这个setter在我代理它时不给我截取的值?

Javascript 为什么这个setter在我代理它时不给我截取的值?,javascript,es6-proxy,Javascript,Es6 Proxy,我确信我创建代理的方法是正确的,因为当我将属性登录到devtools控制台时,我可以看到setter已被代理 如果属性是函数,那么问题就不会发生,它们的拦截工作正常 我主要是按照这个答案来构建这个。尽管如此,我必须说,这个答案看起来很复杂,难以理解,所以我从中剥离了很多东西,形成了一种简单的风格,你们可以从下面的代码中看到 类钩子{ 构造函数(对象){ 如果(对象){ this.object=对象; } } 添加(对象){ this.object=对象; } 代理(处理程序){ 返回新代理(t

我确信我创建代理的方法是正确的,因为当我将属性登录到devtools控制台时,我可以看到setter已被代理

如果属性是函数,那么问题就不会发生,它们的拦截工作正常

我主要是按照这个答案来构建这个。尽管如此,我必须说,这个答案看起来很复杂,难以理解,所以我从中剥离了很多东西,形成了一种简单的风格,你们可以从下面的代码中看到

类钩子{
构造函数(对象){
如果(对象){
this.object=对象;
}
}
添加(对象){
this.object=对象;
}
代理(处理程序){
返回新代理(this.object,handler);
}
};
const hook=新hook();
Object.getOwnPropertyNames(CanvasRenderingContext2D.prototype).forEach(函数(属性){
让propertyDescription=Object.getOwnPropertyDescriptor(CanvasRenderingContext2D.prototype,property);
常量proxyPropertyDescription={
可配置:propertyDescription.configurable,
可枚举:propertyDescription.enumerable
}
if(typeof propertyDescription.value==“函数”){
常量句柄={
应用(目标、此参数、参数){
//对底层函数的前向调用
log(“应用”,thisArg,target,args)
返回target.apply(thisArg,thisArg,args)
}
};
hook.add(propertyDescription.value)
proxyPropertyDescription.writable=propertyDescription.writable;
proxyPropertyDescription.value=hook.proxy(handle,true);
}
if(propertyDescription.set){
常量句柄={
设置(目标、键、值){
//转发对基础属性的访问
设置(目标、关键、价值);
console.log(“设置”、目标、键、值);
}
};
hook.add(propertyDescription.set)
proxyPropertyDescription.set=hook.proxy(handle,true);
}
Object.defineProperty(CanvasRenderingContext2D.prototype、属性、proxyPropertyDescription);
})
var canvas=document.createElement(“canvas”);
var ctx=canvas.getContext(“2d”);
//我的目标,但它永远不会被代理
ctx.font=“14px‘Arial’”;
//但像这样的功能是有效的。。。。
ctx.填充(“红色”);
//我可以在Devtools上看到,当我记录此属性时,它已设置为Proxy

log(Object.getOwnPropertyDescriptor(canvasrendingcontext2d.prototype,“font”)不要将getter/setter与代理混合使用。使用其中一个,而不是两个

以下是仅使用属性描述符的解决方案:

const hook={
wrapMethod(名称、方法){
返回函数(…args){
log(“应用方法”+名称,args);
返回方法。应用(此参数为args);
};
},
包装机(名称、设置器){
返回函数(值){
console.log(“设置”+名称、值);
返回setter.call(这个值);
};
}
};
const proto=canvasrendingcontext2d.prototype;
for(Object.getOwnPropertyNames(proto)的常量名){
常量描述符=Object.getOwnPropertyDescriptor(proto,name);
如果(!descriptor.configurable){
log(“无法挂接到不可变的。”+name);
继续;
}else if(typeof descriptor.value==“函数”){
descriptor.value=hook.wrapMethod(名称、descriptor.value);
}else if(descriptor.set){
descriptor.set=hook.wrapSetter(名称,descriptor.set);
}否则{
log(“未连接到“+名称,描述符”);
}
Object.defineProperty(proto、name、descriptor);
}
var canvas=document.createElement(“canvas”);
var ctx=canvas.getContext(“2d”);
ctx.font=“14px‘Arial’”;
ctx.fillStyle=“红色”;

ctx.fillRect(130、190、40、60)“当我记录此属性时,我可以在Devtools上看到它已设置为代理”-我不能。唉,代理属性描述符是没有意义的。您只需要包装原始setter,在这里使用代理没有意义。最好是将
ctx
本身包装在代理中。此外,
propertyDescription.set
是一个在设置属性时调用的函数。这将触发该函数周围代理的
apply
陷阱,而不是
set
陷阱。@Bergi请参见,Object.defineProperty(CanvasRenderingContext2D.prototype,property,proxyPropertyDescription)@Bergi I使用新的描述重新定义属性。这是我之前链接的问题的处理方式。有趣的是,如果属性是一个函数,那么代理可以很好地工作,但当涉及到getter、setter时,它不是,而我链接的问题本身可以很好地工作@Bergi否。我使用propertyDescription.set检查属性是setter还是getter…为什么要将函数分配给canvasProto.getContext?我需要它独立于HTML5Canvas元素工作。我仍然不能完全理解你的代码。我可以理解你的第一个代码,它重新组装了我自己的代码,但第二个代码非常难…你在评论中说“我想截取每一个上下文。这必须通过renderingContext的原型来完成。”。如果您想使用代理(我想说您不应该这样做),您需要拦截上下文的创建,这就是被覆盖的
getContext
所做的。所以,是的,只使用第一种方法。是的,代理似乎没有任何好处。。