我需要在 JavaScript 中模拟调用一个函数。为此,我将函数“保存”在临时变量中,用新函数 block 更新目标,调用目标,然后恢复旧函数:
var myObject = {
myIntProp: 1,
myFunc: function(value) {
alert(value + 1);
}
};
myObject.myFunc(2);
var tmp = myObject.myFunc;
myObject.myFunc = function(value) {
alert(value - 1);
};
myObject.myFunc(2);
myObject.myFunc = tmp;
myObject.myFunc(2);
这按预期工作:函数被覆盖,然后成功恢复。我的想法是将这段代码移动到辅助函数中,并在需要时轻松使用它:
function FunctionSwapper(target, newFunction) {
var old = target;
target = newFunction;
this.Restore = function() {
target = old;
}
};
var myObject = {
myIntProp: 1,
myFunc: function(value) {
alert(value + 1);
}
};
myObject.myFunc(2);
var swapp = new FunctionSwapper(myObject.myFunc, function(value) {
alert(value - 1);
});
myObject.myFunc(2);
swapp.Restore();
myObject.myFunc(2);
然而,此代码不会保存当前状态,也不会替换目标函数。我在这里错过了什么?函数不是总是作为引用传递吗?这两个代码片段之间的主要区别是什么?
(可用 JSFiddle,但要准备 8 个 alert
...)
编辑:一位用户指出,第二种方法与第一种方法并没有真正的区别,可能不值得创建额外的类;虽然我确实理解并同意他们的论点,但我看到第二种方法有两个优点(都适用于我的特殊、真实案例):
- 在处理具有多个级别的对象时,编写
swapp.Restore();
比myNameSpace.level2.level3.level4.level5 = swap;
更容易/更快子元素和, - 它抽象操作,在开发团队中提供一致的使用(此外,日志记录或类型验证可以在类中完成)。
最佳答案
发生这种情况是因为 target
不是真正的引用,它是引用 target
函数的值。
但是当你重新分配目标时,你并没有修改持有的值(对函数的引用),而是直接修改了值,这意味着你不能这样做。
相反,您可以传递包含要替换函数的对象(它只适用于一个对象,因为您稍后需要访问它)。
这是我想出来的
function FunctionSwapper(target, name, newFunction) {
var old = target[name];
target[name] = newFunction;
this.Restore = function() {
target[name] = old;
}
};
var myObject = {
myIntProp: 1,
myFunc: function(value) {
alert(value + 1);
}
};
myObject.myFunc(2);
var swapp = new FunctionSwapper(myObject, 'myFunc', function(value) {
alert(value - 1);
});
myObject.myFunc(2);
swapp.Restore();
myObject.myFunc(2);
关于javascript - 覆盖和恢复功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31137686/