我需要在JavaScript中模拟调用函数。为此,我将函数“保存”在临时变量中,使用新的功能块更新目标,调用目标然后恢复旧函数:
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
s ...)
编辑:一位同事已经指出第二种方法与第一种方法没有什么不同,而且创建额外的类可能不值得。虽然我理解并同意他们的论点,但我认为第二种方法有两个优点(两者都适用于我的特定,现实案例):
swapp.Restore();
比myNameSpace.level2.level3.level4.level5 = swap;
更容易/更快,答案 0 :(得分:5)
这是因为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);
答案 1 :(得分:3)
FunctionSwapper
正在恢复自己的功能副本,但它与myObject
没有任何关联(您不会将其传递给myObject
)。
这样可行:
function FunctionSwapper(object,name,newFunction) {
var old = object[name];
object[name] = newFunction;
this.Restore = function() {
object[name] = old;
}
};
...
var swapp = new FunctionSwapper(myObject, "myFunc", function(value) {
alert(value - 1);
});
答案 2 :(得分:3)
我相信通过传递myObject.myFunc
,您实际上会从myObject
中断参考,因此它实际上并未更新myFunc
myObject
的{{1}}来电,它会更新FunctionSwapper
副本的本地范围。
将它与此进行比较,它对对象本身执行操作:
function FunctionSwapper(obj, funcName, newFunction) {
var old = obj[funcName];
obj[funcName] = newFunction;
this.Restore = function() {
obj[funcName] = 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);