admin管理员组文章数量:1332377
when i try to call a function inside the object using "this" from a callback function, an error occur saying that the method is undefined. How can I solve this issue!.
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");
}
};
when i try to call a function inside the object using "this" from a callback function, an error occur saying that the method is undefined. How can I solve this issue!.
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");
}
};
Share
asked Jan 8, 2014 at 22:48
Moussawi7Moussawi7
13.3k7 gold badges38 silver badges50 bronze badges
2
-
Where is
this.success
defined? – elclanrs Commented Jan 8, 2014 at 22:49 - My code is too Long, that because I create an example. so sorry, let me edit it – Moussawi7 Commented Jan 8, 2014 at 22:50
2 Answers
Reset to default 4You need to use the .call()
or .apply()
methods on the callback to specify the context which the method is called upon.
The callback method remote_submit
does not know what this
will be anymore and thus when it calls the callback methods they're executed like normal functions not on an object.
You can "Bind" your functions by wrapping them on the way out:
var self = this;
remote_submit(
identify,
function() { return self.success.apply(self, arguments); },
function() { return self.error.apply(self, arguments); }
);
This allows you to pass the context in the closure of the anonymous function and execute the callbacks with an exclusive this
context.
It appears that in EMCAScript5+ you can use bind
on the function to bind it for use in a callback:
remote_submit(identify, this.success.bind(), this.error.bind())
However from the 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.
The shim/polyfill is here:
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:
To answer your additional question, let's first look at the call
and apply
documentation and break down how they work:
Fundamentally they work the same, the only difference is how they take their arguments:
myfunc.call(target, param1, param2, param3);
Will call myfunc(param1, param2, param3)
with target
as this
.
var args = [param1, param2, param3];
myfunc.apply(target, args);
Will call myfunc(param1, param2, param3)
with target
as this
.
Basically the difference is that .apply()
takes an array of arguments, where the call
function requires you to write in the arguments in the code.
Next, if we look at the example i gave you:
function() { return self.success.apply(self, arguments); }
This returns a function that will call your callback by passing all the arguments (arguments
variable) that were passed into the anonymous function, onto the apply
function. So:
var a = function() { return self.success.apply(self, arguments); };
a(1,2,3,4);
This will call self.success(1,2,3,4)
with self
as this
. If you'd like to augment the arguments with something specific for example if you wanted a(1,2,3,4)
to call self.success(self.test, 1, 2, 3, 4)
then you'll have to provide an augmented array to the apply
function:
var a = function() {
var args = [self.test];
for(var i = 0; i < arguments.length; i++) args[] = arguments[i];
return self.success.apply(self, args);
}
When you pass the function as a callback, do it like this:
whatever( object_log.login.bind( object_log ) );
That call to the .bind
method will return a function that'll make sure your "login" function will be called such that this
references the "object_log" object.
There's a good shim for .bind
for older browsers at the MDN documentation site.
本文标签: javascript call function inside objectfrom a callback functionStack Overflow
版权声明:本文标题:javascript: call function inside object, from a callback function - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742295154a2448575.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论