Ok, so I thought I understood this (no pun intended), but apparently not.
var Constructor = function () {
var internalFunction = function () {
return this === window;
};
this.myMethod = function () {
alert(internalFunction());
};
};
var myObj = new Constructor();
myObj.myMethod();
This alerts true
. Why can't the internal function see this
as the object? Instead I have to use alert(internalFunction.call(this));
in myMethod
.
Edit: I was looking for an explanation as to why this
is assigned in that way, not workarounds such as var self = this;
, etc. Sorry if I didn't make that clear.
this
is not bound until the function is called and is dependent on how the function is called. You could think of it as an extra parameter implicitly passed to the function.
In this case, the problem is that you're calling internalFunction
using internalFunction()
. The this
value is set either by calling a function as a method (as in foo.bar()
or foo["bar"]()
) or by setting this
explictly via call()
or apply()
. Your call is doing neither so this
reverts to the global object.
The simplest way to achieve what you want in this case while keeping internalFunction
private is to store a reference to this
inside the constructor function:
var Constructor = function() {
var thisObj = this;
var internalFunction = function () {
return thisObj === window;
};
thisObj.myMethod = function () {
alert(internalFunction());
};
}
Because of functional scoping rules, this
is reassigned inside each function... I would store a copy of your object as self
and use it accordingly...
var Constructor = function () {
var self = this;
var internalFunction = function () {
return self === window;
};
this.myMethod = function () {
alert(internalFunction());
};
};
var myObj = new Constructor();
myObj.myMethod();
Should give you the output you expect.
SIDENOTE
This is a fairly precarious practice that javascript has created, mainly because if you forget the new
keyword when using Constructor
, you will get this
referring to the window
(god) object so you'll be attaching myMethod
to the window without warning.
There are five ways to call a function in JavaScript. The value of this
depends on which you choose:
- Global function call (e.g.
myFunction()
). No explicit value for this
is given. The value of this
will be the default object (window
in a browser).
- Method call (e.g.
obj.myFunction()
). The value of this
is the object on which the method was invoked (obj
in this case).
- Using the
call
method (e.g. myFunction.call(obj)
). The value of this
is provided explicitly (in this case obj
).
- Using the
apply
method (e.g. myFunction.apply(obj)
). The value of this
is provided explicitly (in this case obj
).
- Constructor function (e.g.
new MyFunction()
). The value of this
is a newly-created object provided by the runtime.
Each of the five is explained in more detail here:
- http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
Its a scope issue try something like:
var Constructor = function () {
var $this = this;
var internalFunction = function () {
return $this === window;
};
this.myMethod = function () {
alert(internalFunction());
};
};
var myObj = new Constructor();
myObj.myMethod();