你需要在回调函数上使用
.call()
或
.apply()
方法,以指定方法被调用时的上下文。
当回调方法
remote_submit
调用回调函数时,它不再知道
this
代表什么,因此当它调用回调函数时,它们会像普通函数一样执行,而非作为对象上的方法执行。
你可以通过包装函数来“绑定”它们:
var self = this;
remote_submit(
identify,
function() { return self.success.apply(self, arguments); },
function() { return self.error.apply(self, arguments); }
);
这样可以在匿名函数的闭包中传递上下文,并使用独占的this
上下文执行回调函数。
在EMCAScript5+中,似乎可以使用bind
函数将其绑定以在回调函数中使用:
remote_submit(identify, this.success.bind(), this.error.bind())
然而,从
MDN文档中可以看到:
bind函数是ECMA-262第5版的最新补充内容。因此,它可能不会在所有浏览器中出现。您可以通过在脚本开头插入以下代码来部分解决此问题,在不支持原生bind()功能的实现中使用大部分bind()功能。
这里提供了shim/polyfill:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
更新:
回答您的附加问题,让我们首先查看
call 和
apply 的文档并分解它们的工作原理:
基本上它们的工作方式相同,唯一的区别是它们如何使用它们的参数:
myfunc.call(target, param1, param2, param3);
将会使用target
作为this
,调用myfunc(param1, param2, param3)
。
var args = [param1, param2, param3];
myfunc.apply(target, args);
将使用target
作为this
参数,调用myfunc(param1, param2, param3)
。
基本上区别在于.apply()
需要传入一个数组作为参数,而call
函数需要你在代码中写入参数。
接下来,如果我们看一下我给你的例子:
function() { return self.success.apply(self, arguments); }
这将返回一个函数,该函数将通过传递匿名函数中传递的所有参数(arguments
变量)到apply
函数,从而调用您的回调函数。因此:
var a = function() { return self.success.apply(self, arguments); };
a(1,2,3,4);
这将使用this
作为self
来调用self.success(1,2,3,4)
函数。如果您想要增加一些特定的参数,例如,如果您想要a(1,2,3,4)
调用self.success(self.test, 1, 2, 3, 4)
函数,那么您需要提供一个增强的数组给apply
函数:
var a = function() {
var args = [self.test];
for(var i = 0; i < arguments.length; i++) args[] = arguments[i];
return self.success.apply(self, args);
}
this.success
定义在哪里? - elclanrs