About Call:
You can sort of solve this issue by using .call()
which:
- must be called on a function
addName.call()
- you pass it an object of what you want to be the "this"
addName.call({"name" : 'angela'});
- you can pass additional arguments that can be used in the function it is called on
addName.call({"name": "angela"}, true);
where perhaps addName
accepts an argument of boolean append
.
Use Call:
For this particular problem, we can pass the "parent" object through call
to override the this
normally present in the child object.
Look at our problem first
var app = {
init: function() {
var _this = this; // so we can access the app object in other functions
$('#thingy').click(function(){
alert(_this.options.thingy());
});
$('#another').click(function(){
alert(_this.options.getAnother());
});
},
options: {
thingy: function() {
// PROBLEM: the this here refers to options
return this.getThingy();
},
getAnother: function() {
// PROBLEM 2: we want the this here to refer to options,
// but thingy will need the parent object
return 'another ' + this.thingy();
},
},
getThingy: function() {
return 'thingy';
}
};
Now, here's a solution use call
And JSFIDDLE to see it work.
var app = {
init: function() {
var _this = this; // so we can access the app object in other functions
$('#thingy').click(function(){
// SOLUTION: use call to pass _this as the 'this' used by thingy
alert(_this.options.thingy.call(_this));
});
$('#another').click(function(){
// SOLUTION 2: Use call to pass parent all the way through
alert(_this.options.getAnother.call(_this));
});
},
options: {
thingy: function() {
// SOLUTION in action, the this is the app object, not options.
return this.getThingy();
},
getAnother: function() {
// SOLUTION 2 in action, we can still access the options
// AND pass through the app object to the thingy method.
return 'another ' + this.options.thingy.call(this);
},
},
getThingy: function() {
return 'thingy';
}
};
In conclusion
You can use .call()
whenever you use a method on a property of your main object: app.options.someFunction(arg)
should always be called with .call
- app.options.someFunction.call(this, arg);
- that way you can ensure that you'll always have access to every part of the object. It could give you access to another property's methods like app.helpers.anotherFunction()
.
A good idea is in the somefunction
, store this
in a variable _parentThis
so it's obvious what the this
reflects.