在引用原文的同时覆盖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);