您需要使用.call()
or .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 文档:
绑定函数是 ECMA-262 第 5 版的最新新增内容;因此,它可能并不存在于所有浏览器中。您可以通过在脚本开头插入以下代码来部分解决此问题,从而允许在本机不支持它的实现中使用bind()的大部分功能。
垫片/填充材料在这里:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable 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;
};
}
Update:
为了回答您的附加问题,我们首先看一下call and apply文档并分解它们的工作原理:
从根本上来说,他们的工作原理是相同的,唯一的区别是他们如何看待他们的论点:
myfunc.call(target, param1, param2, param3);
将会通知myfunc(param1, param2, param3)
with target
as this
.
var args = [param1, param2, param3];
myfunc.apply(target, args);
将会通知myfunc(param1, param2, param3)
with target
as this
.
基本上区别在于.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);
这将调用self.success(1,2,3,4)
with self
as this
。如果您想用特定的东西来增强论据,例如如果您想要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);
}