Answers:
您可以执行以下操作:
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
。
(functi..
和})
。这样做}();
会产生相同的结果,因为使用了(function{})()
第一组括号,因为您不能只声明匿名函数表达式而必须为其分配值。但是通过执行(),您并没有定义任何东西,只是返回一个函数。
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 );
};
})();
上面的代码将其包装在一个函数中,以隐藏“代理”变量。它将jQuery的setArray方法保存在一个闭包中并覆盖它。然后,代理将所有调用记录到该方法,并将该调用委托给原始方法。使用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);
}
};
谢谢,这真的帮助了我
org_foo(args)
call org_foo.call(this, args)
。这保持this
了window.foo正常调用(未代理)时的状态。看到这个答案
您可以使用类似以下的结构来覆盖函数:
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(); }
});
编辑:修正了一个错字。
@Matthew Crumley提供的答案是利用立即调用的函数表达式,将较旧的“ a”函数关闭到返回函数的执行上下文中。我认为这是最好的答案,但就我个人而言,我更愿意将函数“ a”作为参数传递给IIFE。我认为这是可以理解的。
var a = (function(original_a) {
if (condition) {
return function() {
new_code();
original_a();
}
} else {
return function() {
original_a();
other_new_code();
}
}
})(a);
上面的示例未正确应用this
或arguments
正确传递给函数重写。下划线_.wrap()包装现有函数,应用this
并arguments
正确传递。请参阅:http://underscorejs.org/#wrap
我有一些其他人编写的代码,想在代码中找不到的函数上添加一行。因此,作为一种解决方法,我想覆盖它。
但是,没有一种解决方案对我有用。
这是我的情况下有效的方法:
if (typeof originalFunction === "undefined") {
originalFunction = targetFunction;
targetFunction = function(x, y) {
//Your code
originalFunction(a, b);
//Your Code
};
}
我为类似的情况创建了一个小助手,因为我经常需要覆盖多个库中的函数。该帮助器接受一个“命名空间”(函数容器),函数名称和重写函数。它将用新的命名空间替换所引用的命名空间中的原始函数。
新函数将原始函数作为第一个参数,并将原始函数作为其余参数。它将每次都保留上下文。它也支持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
});
我没有创建任何性能测试。它可能会增加一些不必要的开销,根据情况的不同,开销可能很大,也可能不会很大。
因此,我的答案最终是一个解决方案,使我可以使用_this变量指向原始对象。我创建了一个“ Square”的新实例,但是我讨厌“ Square”生成其大小的方式。我认为它应该符合我的特定需求。但是,为了做到这一点,我需要正方形具有更新的“ GetSize”函数,该函数的内部调用该正方形中已经存在的其他函数,例如this.height,this.GetVolume()。但是为了做到这一点,我需要做到这一点而没有任何疯狂的破解。所以这是我的解决方案。
其他一些对象初始化器或帮助器函数。
this.viewer = new Autodesk.Viewing.Private.GuiViewer3D(
this.viewerContainer)
var viewer = this.viewer;
viewer.updateToolbarButtons = this.updateToolbarButtons(viewer);
在另一个对象中起作用。
updateToolbarButtons = function(viewer) {
var _viewer = viewer;
return function(width, height){
blah blah black sheep I can refer to this.anything();
}
};
不知道它是否在所有情况下都能正常工作,但是在我们的案例中,我们试图覆盖describe
Jest中的函数,以便我们可以解析名称,并在describe
满足某些条件的情况下跳过整个块。
这是对我们有用的东西:
function describe( name, callback ) {
if ( name.includes( "skip" ) )
return this.describe.skip( name, callback );
else
return this.describe( name, callback );
}
这里至关重要的两件事:
我们不使用箭头功能() =>
。
箭头函数会更改对的引用this
,我们需要将其作为文件的this
。
使用this.describe
和this.describe.skip
代替正义describe
和describe.skip
。
再次重申,不确定是否对任何人有价值,但我们最初试图摆脱Matthew Crumley的 出色回答,但需要使我们的方法成为函数并接受参数,以便在条件条件下解析它们。