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 不是函数
很明显我做错了什么,我想做的就是覆盖函数,以便它返回与原始方法不同的东西。
答案 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);
}
);