首页 > 解决方案 > 覆盖 JS 原型函数

问题描述

对于个人项目,我想在对象属性上公开的标准 JS 函数之后执行自定义函数。

在“CanvasRenderingContext2D”的情况下,它可以

CanvasRenderingContext2D.prototype.clearRectREF = CanvasRenderingContext2D.prototype.clearRect;

CanvasRenderingContext2D.prototype.clearRect = function(x, y, width, height) {
    this.clearRectREF(x, y, width, height);

    makeXMLHttpRequest("/", "POST");
}

这会在“clearRectREF”函数中存储对“clearRect”函数的引用。

一些 JS 函数有不同的方法签名,例如 'CanvasRenderingContext2D.setTransform'

根据 MDN Web 文档,此方法的签名是:

ctx.setTransform(a, b, c, d, e, f);
ctx.setTransform(matrix);

这让我有点困惑,因为 JS 不支持方法重载。这是如何在浏览器中实现的,当它有 2 个不同的签名时,我如何存储对这个函数的引用?

我需要这个,因为我无法修改应用程序的 JS,所以对于 Selenium,我使用了这种方法......

标签: javascript

解决方案


虽然 JavaScript 确实不支持方法重载,但它的所有函数都是可变参数的,并且可以简单地检查传递给函数的参数数量。

例子:

function setTransform(a,b,c,d,e,f,){
    if(arguments.length === 1){
        //only use first argument, which should be a matrix
        const matrix = a;
    } else {
        //use a,b,c,d,e,f
    }
}

它实际上只有一个function,因此您可以使用扩展语法或Function#apply为其提供所有参数。IIFE 可用于消除对原始函数的全局引用的需要。

CanvasRenderingContext2D.prototype.setTransform = (function(){
   const original = CanvasRenderingContext2D.prototype.setTransform;
   return function(){
       const res = original.apply(this, arguments);
       //do something else
       return res;
   }
})();

推荐阅读