覆盖/覆盖javascript中的函数

时间:2021-04-20 10:00:05

标签: javascript

javascript 库中有一个函数,我想为我自己的用例覆盖,我想使用该函数中的大部分代码,但添加一些额外的功能。在我的控制台中,我可以通过执行 somelibrary.CharCounter.prototype.count 这个函数接受一个文本参数来访问该函数。

我尝试了以下方法,

somelibrary.CharCounter.prototype.count = (function(_super, text) {
   return function(_super, apply) {
       console.log("overwriting", text);
       return _super.apply(this, arguments);
   };
})(somelibrary.CharCounter.prototype.count)

在上面我得到了我所期望的console.log,但我也得到了这个错误,

<块引用>

未捕获的类型错误:_super.apply 不是函数

很明显我做错了什么,我想做的就是覆盖函数,以便它返回与原始方法不同的东西。

3 个答案:

答案 0 :(得分:1)


您必须仅将 _super 传递给外部函数并使内部函数接受“超级”参数:

Array.prototype.slice = (function(_super) {
   return function(x, y) {
       console.log("overwriting", x, y);
       return _super.apply(this, arguments);
   };
})(Array.prototype.slice);


console.log([1,2,3,4,5,6].slice(1,3))

为了避免重复,您可能需要定义一个通用函数:

function override(obj, method, fn) {
    let prev = obj[method]

    obj[method] = function (...args) {
        return fn.call(
            this,
            prev.bind(this),
            ...args,
        )
    }
}


override(Array.prototype, 'slice', function (_super, x, y) {
    console.log("overwriting", x, y);
    return _super(x, y + 1)
})


console.log([1,2,3,4,5,6].slice(1,3))

答案 1 :(得分:1)

您可以为此使用 Proxy。以下是代理 Math.sin 的演示:

Math.sin = new Proxy(Math.sin, {
    apply: function(original, thisArg, args) {
        console.log(`Executing ${original.name}(${args.join()})`);
        return original.apply(thisArg, args);
    }
});

console.log(Math.sin(2));

答案 2 :(得分:0)

也许稍微更具可读性的解决方案:

somelibrary.CharCounter.prototype.foo = (function () {
  var _super = somelibrary.CharCounter.prototype.foo;
  return function (text) {
    console.log("overwriting", text);
    return _super.apply(this, arguments);
  }
})();

也可以为覆盖函数定义通用的 extendFunction() 函数:

function extendFunction(superFunc, overridingFunc) {
  return function () {
    overridingFunc.call(this, superFunc, arguments);
  }
}

somelibrary.CharCounter.prototype.foo = extendFunction(
  somelibrary.CharCounter.prototype.foo,
  function (superFunc, args) {
    console.log("overwriting", args);
    return superFunc.apply(this, args);
  }
);