i have JavaScript components, that has following architecture:
var MyComponent = function(params)
{
setup(params);
this.doSomething()
{
// doing something
};
function setup(params)
{
// Setup
// Interaction logic
var _this = this; // "this" points to DOMWindow, not to created object
$(".some-element").click(function(){
_this.doSomething(); // it craches here, because of above
});
}
};
When something, being controlled by interaction logic, happens, sometimes i must forward execution to “public” methods of component.
In this situation, i have a problem with “this” pointer.
Sample code demonstrates it:
var Item = function()
{
this.say = function()
{
alert("hello");
};
this.sayInternal = function()
{
_sayInternal();
};
function _sayInternal()
{
this.say();
};
};
To test it,
- Create an object:
var o = new Item();
- This works fine:
o.say(); // alerts "hello"
- This crashes:
o.sayInternal();
I get an error:
TypeError: Result of expression ‘this.say’ [undefined] is not a function.
I think, such a behaviour takes place, because _sayInternal() function is declared (and not assigned to object, like “this.say = function()”). This way, it is shared across all created objects and acts like a static function in C++.
Is this true ?
No,
sayInternalis not shared between created objects. But you are right, the created objects don’t have access tosayInternalas it is not assigned to them. This function is only local to the constructor function.thisalways refers to the context a function is invoked in. If you call it likefunc(), thenthisrefers to the global object (which iswindowin browser). If you set the function as property of an object and call it withobj.func(), thenthiswill refer toobj.If you assign a “bound” function to a variable and call it:
then
thiswill again refer to the global object. In JavaScript, functions are like any other value, they don’t have a special relationship to the object they are assigned to.You can explicitly set the context with
callorapply:or in you other example:
That said, this approach to assign functions to objects is not good, because every instance will have its own
this.sayInternalfunction. So for theItemcode above, every creation of an instance involves creating three functions too, which is a waste of memory.Making use of prototype inheritance would be a better way:
This way,
_sayInternalis only created once and all instances inherit (refer to) the prototype, sosayandsayInternalalso exist only once. The “trick” with the immediate function makes_sayInternalonly accessible bysayandsayInternal.