我正在尝试为canvas上下文中调用的每个方法添加一些代码。我试图这样做,所以我可以将每个命令添加到一个命令数组。这是我认为有效的代码(但不是):
var canvas = Object.getPrototypeOf(document.createElement('canvas').getContext('2d'));
for(p in canvas){
if(canvas.hasOwnProperty(p)){
var original = canvas[p];
canvas[p] = function(){
//extra code to be run
return original.apply(this,arguments);
}
}
}
在我看来,它应该可行,但事实并非如此。如果我在示例中使用此代码,则会得到NOT_SUPPORTED_ERR: DOM Exception 9
答案 0 :(得分:5)
您遇到的问题是变量不是块范围的。
当你的函数运行时,它会更新上下文原型,以便每个函数调用相同的函数original
,这是原始原型拥有的最后一个元素。在这种情况下,即webkitGetImageDataHD
。
这意味着当您致电ctx.beginPath();
时,您确实致电ctx.webkitGetImageDataHD();
。这个方法需要4个参数,因为它没有得到它们,它会抛出DOM异常9。
由于JavaScript不支持块范围,因此必须使用函数强制更改范围。修改您的示例,我们可以创建一个新函数,其中original
是固定值:
var context = Object.getPrototypeOf(document.createElement('canvas').getContext('2d'));
function bind(context, p) {
// context, p, and original never change.
var original = context[p];
context[p] = function(){
console.log(p, arguments);
return original.apply(this,arguments);
}
}
// p changes with every iteration.
for(p in context){
if(context.hasOwnProperty(p)){
bind(context, p);
}
}
在此处查找有效的演示:http://jsfiddle.net/bnickel/UG9gF/
答案 1 :(得分:2)
JavaScript没有块范围,并且只有一个original
变量包含最后一个枚举函数。
此解决方案不会更改上下文原型(host object!),只会更改myContext
的副本:
var myContext = someCanvas.getContext('2d');
var CanvasRenderingContext2DPrototype = Object.getPrototypeOf(myContext);
for (var p in CanvasRenderingContext2DPrototype) (function(original, prop) {
myContext[prop] = function() {
// some extra code
original.apply(myContext, arguments);
};
})(CanvasRenderingContext2DPrototype[p], p);