在引用原文的同时覆盖JavaScript函数

我有一个函数, a() ,我想重写,但也有原始的a()按顺序执行取决于上下文。 例如,有时当我生成一个页面,我想要这样重写:

 function a() { new_code(); original_a(); } 

有时候是这样的:

 function a() { original_a(); other_new_code(); } 

我如何从顶部的a()获得original_a() a() ? 这甚至有可能吗?

请不要以这种方式build议替代scheme,我知道很多。 我正在问这个具体的方式。

你可以做这样的事情:

 var a = (function() { var original_a = a; if (condition) { return function() { new_code(); original_a(); } } else { return function() { original_a(); other_new_code(); } } })(); 

在匿名函数中声明original_a可以避免混淆全局名称空间,但它在内部函数中可用。

就像在评论中提到的Nerdmaster一样,一定要包括()在最后。 你想调用外部函数并将结果 (两个内部函数之一)存储在a ,而不是将外部函数本身存储在a

代理模式可能会帮助您:

 (function() { // log all calls to setArray var proxied = jQuery.fn.setArray; jQuery.fn.setArray = function() { console.log( this, arguments ); return proxied.apply( this, arguments ); }; })(); 

上面的代码包含在一个函数中以隐藏“代理”variables。 它将jQuery的setArray方法保存在闭包中并覆盖它。 代理然后logging对该方法的所有调用并将该调用委托给原始。 使用apply(this,arguments)可以保证调用者不会注意到原始代码和代理方法之间的区别。

感谢球员的代理模式真的帮助…..其实我想要调用一个全局函数foo ..在某些页面,我需要做一些检查。 所以我做了以下。

 //Saving the original func var org_foo = window.foo; //Assigning proxy fucnc window.foo = function(args){ //Performing checks if(checkCondition(args)){ //Calling original funcs org_foo(args); } }; 

Thnx这真的帮了我

你可以使用如下构造来覆盖函数:

 function override(f, g) { return function() { return g(f); }: } 

例如:

  a = override(a, function(original_a) { if (condition) { new_code(); original_a(); } else { original_a(); other_new_code(); } }); 

传递任意参数:

 a = override(a, function(original_a) { if (condition) { new_code(); original_a.apply(this, arguments) ; } else { original_a.apply(this, arguments); other_new_code(); } }); 

上面的例子没有正确地应用this或正确的传递arguments给函数覆盖。 Underscore _. wrap()包装现有的函数,应用this并正确地传递arguments 。 请参阅: http : //underscorejs.org/#wrap

我有一些别人编写的代码,并希望添加一个函数,我无法在代码中find。 所以作为一个解决方法,我想重写它。

没有解决scheme为我工作。

这是什么在我的情况下工作:

 if (typeof originalFunction === "undefined") { originalFunction = targetFunction; targetFunction = function(x, y) { //Your code originalFunction(a, b); //Your Code }; } 

我为类似的场景创build了一个小帮手,因为我经常需要重写几个库的函数。 这个助手接受一个“命名空间”(函数容器),函数名和覆盖函数。 它将用新的名称空间replace引用的名称空间中的原始函数。

新函数接受原始函数作为第一个参数,原始函数参数作为其余部分。 每次都会保存上下文。 它支持void和non-void函数。

 function overrideFunction(namespace, baseFuncName, func) { var originalFn = namespace[baseFuncName]; namespace[baseFuncName] = function () { return func.apply(this, [originalFn.bind(this)].concat(Array.prototype.slice.call(arguments, 0))); }; } 

用例如Bootstrap:

 overrideFunction($.fn.popover.Constructor.prototype, 'leave', function(baseFn, obj) { // ... do stuff before base call baseFn(obj); // ... do stuff after base call }); 

我没有创build任何性能testing。 它可能会添加一些不必要的开销,这可能或不是一个大问题,取决于情况。

在我看来,最重要的答案是不可读/可维护的,其他答案没有正确地绑定上下文。 这是一个使用ES6语法解决这两个问题的可读解决scheme。

 const orginial = someObject.foo; someObject.foo = function() { if (condition) orginial.bind(this)(...arguments); }; 

@Matthew Crumley提供的答案是利用立即调用的函数expression式,将旧的'a'函数closures到返回函数的执行上下文中。 我认为这是最好的答案,但个人而言,我更愿意把函数“a”作为parameter passing给IIFE。 我觉得这是可以理解的。

  var a = (function(original_a) { if (condition) { return function() { new_code(); original_a(); } } else { return function() { original_a(); other_new_code(); } } })(a);