当我尝试使用回调函数中的“this”调用对象内部的函数时,出现错误,指出该方法未定义。 我该如何解决这个问题!
var object_log = {
user: "",
pass: "",
error_message: "an error occured while connecting",
init: function(user, pass) {
this.user = user;
this.pass = pass;
},
login: function() {
remote_submit(identify, this.success, this.error);
},
error: function() {
alert(this.error_message);
},
success: function() {
alert("success");
}
};
最佳答案
您需要在回调上使用 .call()
或 .apply()
方法来指定调用该方法的上下文。
回调方法 remote_submit
不再知道 this
是什么,因此当它调用回调方法时,它们就像普通函数一样执行,而不是在对象上。
您可以通过在输出时包装它们来“绑定(bind)”您的函数:
var self = this;
remote_submit(
identify,
function() { return self.success.apply(self, arguments); },
function() { return self.error.apply(self, arguments); }
);
这允许您在匿名函数的闭包中传递上下文,并使用独占的 this
上下文执行回调。
似乎在 EMCAScript5+ 中,您可以在函数上使用 bind
来绑定(bind)它以便在回调中使用:
remote_submit(identify, this.success.bind(), this.error.bind())
但是来自 MDN Documentation :
The bind function is a recent addition to ECMA-262, 5th edition; as such it may not be present in all browsers. You can partially work around this by inserting the following code at the beginning of your scripts, allowing use of much of the functionality of bind() in implementations that do not natively support it.
shim/polyfill 在这里:
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;
};
}
更新:
为了回答您的附加问题,让我们首先看一下 call
和 apply
文档并分解它们的工作原理:
从根本上说,它们的工作原理是一样的,唯一的区别是它们如何处理它们的论点:
myfunc.call(target, param1, param2, param3);
将调用 myfunc(param1, param2, param3)
并将 target
作为 this
。
var args = [param1, param2, param3];
myfunc.apply(target, args);
将调用 myfunc(param1, param2, param3)
并将 target
作为 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)
并将 self
作为 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);
}
关于javascript:从回调函数调用对象内部的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21008229/