Reputation: 12544
I'm building an app with several 'modules'. Each module requires a similar base set of functionality, so I have created a base module that each module will inherit from via prototypal inheritance. Some of the function names on the base module are quite long, and since these functions are used often, I would like to assign shorter names within each module, but this causes issues with the value of 'this' setting it equal to DOMWindow.
Please see the code below:
var SAMPLEAPP = SAMPLEAPP || {};
//This is a base module that I want all other modules to inherit from
SAMPLEAPP.Module = function(){
};
SAMPLEAPP.Module.prototype.someLongFunctionName = function(){
console.log(this);
};
//This is a module that inherits from the base module
SAMPLEAPP.RouterModule= function(){
var shortName = this.someLongFunctionName;
//This correctly logs 'SAMPLEAPP.RouterModule', but I would rather not type
//out this long function name each time I need to use the function
this.someLongFunctionName();
//However, this code logs 'DOMWindow' when I would expect the value of 'this'
//to be the same as the direct call to this.someLongFunctionName
shortName();
};
SAMPLEAPP.RouterModule.prototype = new SAMPLEAPP.Module();
new SAMPLEAPP.RouterModule();
My Question: How can I modify the code so that calling shortName() logs SAMPLEAPP.RouterModule? If possible, I would rather change the way the modules are defined than the actual call to shortName (i.e. shortname.call(this), defeats the purpose of creating an alias for someLongFunctionName)
Upvotes: 2
Views: 89
Reputation: 13883
Another solution is to use a binding function to bind a new context to the function.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
var shortName = this.someLongFunctionName.bind(this);
Upvotes: 1
Reputation: 166071
As others have mentioned, you can use call
or apply
(either will work, the difference is simply how arguments are passed to the function).
Alternatively, you can use the ES5 bind
method, which binds a context to a function (in this case the context will be this
):
var shortName = this.someLongFunctionName.bind(this);
You can then call shortName
as you normally would:
shortName();
Here's a working example. And here's the most relevant part of the MDN article:
The bind() function creates a new function (a bound function) with the same function body (internal Call attribute in ECMAScript 5 terms) as the function it is being called on (the bound function's target function) with the this value bound to the first argument of bind(), which cannot be overridden.
Upvotes: 2
Reputation: 3634
You can pass the "this" context to the method call, by using the call / apply function. In your case it can be either
shortName.apply(this);
OR
shortName.call(this);
Upvotes: 1
Reputation: 2202
You can change the call to shortName();
to shortName.call(this);
.
The this is javascript is a bit trick. Is based on context.
Upvotes: 0