How do I update the JavaScript this-pointer inside an object to point to another object?
I'm having some trouble with JavaScript and the passing of a function as parameter of another function.
let's say we are inside a class and do something like that:
this.get('target').update(this.onSuccess, this.onFail);
- 'target' is a JavaScript-object that has a method called update()
- I'm calling this method and pass tow methods of the caller-class along as parameters
inside that update-method some stuff happens and when it's 开发者_C百科done that method should either call the onSuccess-method or the onFail-method. this looks something like:
update: function(onSuccess, onFail) {
if(true) {
onSuccess();
} else {
onFail();
}
}
until now, everything works pretty fine! but inside those success/fail-methods, that are defined in the caller-class (the one that calls above update-method), I'm using a this-pointer:
onFail: function() {
alert('Error: ' + this.get('target').error);
}
that this-pointer causes some issues. it doesn't point to the class where the method initially was defined but to the 'target'-object.
what I need to do now is to update the this-pointer right before the onSuccess / onFail calls inside the 'target'-class to make the methods work again. but this doesn't work due to a 'invalid assignment left-hand side'-error.
what is the best practice for a scenario like that? any ideas? thx in advance!!!
cheers
You have two options when calling update()
:
- javascript function
call()
- javascript function
apply()
the main difference being how you pass parameters to it. But they both allow scope/context injection.
Your code should look something like this:
this.get('target').update.call(this, this.onSuccess, this.onFail);
You can create a function that "binds" a function to a certain object (using a closure) and than pass these bound functions to the handler:
function bind(obj, fun) {
return function() {
return fun.apply(obj, arguments);
};
};
update(bind(this, this.onSuccess), bind(this, this.onFail));
To redirect this, you need a bind()
(or similar) method in the Function
class, as found in almost all JavaScript libraries:
if(!Function.prototype.bind){
Function.prototype.bind = function(scope) {
var _function = this;
return function() {
return _function.apply(scope, arguments);
}
}
}
Now do something like this:
update: function(onSuccess, onFail) {
if(true) {
onSuccess.bind(this)();
} else {
onFail.bind(this)();
}
}
The mechanism is explained here: Binding Scope in JavaScript
精彩评论