重写原型方法并调用原始方法

时间:2014-05-30 15:13:50

标签: javascript html5 canvas

我想覆盖Html5 Canvas的drawImage函数。这是代码。

var p = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function() {
    var len = arguments.length;
    var ig, sx, sy, swidth, sheight, x, y, width, height
    if (len === 3) {
        p(arguments[0], arguments[1] * 2, arguments[2] * 2, this);
    } else if (len === 5) {
        //Uncaught TypeError: Illegal invocation.
        p(arguments[0], arguments[1] * 2, arguments[2] * 2, arguments[3] * 2, arguments[4] * 2, this); 
    } else if (len === 9) {
        p(arguments[0], arguments[1] * 2, arguments[2] * 2, arguments[3] * 2, arguments[4] * 2, arguments[5] * 2, arguments[6] * 2, arguments[7] * 2, arguments[8] * 2, this);
    }
}

并按以下方式调用该函数。

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);

但是它会在注释行中引发错误。 在重写原型方法之后,如何调用原始方法。

1 个答案:

答案 0 :(得分:3)

您必须说p.callp.apply才能在正确的上下文中执行它。

if (len === 3) {
    p.call(this, arguments[0], arguments[1] * 2, arguments[2] * 2);
} else if (len === 5) {
    p.call(this, arguments[0], arguments[1] * 2, arguments[2] * 2, arguments[3] * 2, arguments[4] * 2); 
} else if (len === 9) {
    p.call(this, arguments[0], arguments[1] * 2, arguments[2] * 2, arguments[3] * 2, arguments[4] * 2, arguments[5] * 2, arguments[6] * 2, arguments[7] * 2, arguments[8] * 2);
}

编辑:这就是原因。当您调用javascript函数时,默认情况下,它会在window的上下文中执行。这意味着关键字this引用窗口(它不应该;当您调用drawImage时,this应该引用canvas元素)。通过覆盖默认上下文window,您可以将其更改为正确的上下文。

示例:

var w = document.write;
// Error
w("Test");
// Works
w.call(document, "Test");