I understand that Javascript isn't a true OO language and the introduction of ECMAScript 6 should alleviate some of these problems, but the use of the this
keyword in Javascript is genuinely confusing me, at least when trying to replicate "private" functions in Javascript.
Consider the following code:
function Person() {
this.name = "Blake";
var sayHi = function() {
console.log("Salutations. My name is " + this.name);
this.name = "Jon";
console.log("Salutations. My name is " + this.name);
this.sayBye();
};
this.callSayHi = function() {
console.log("O hai, my name is " + this.name);
sayHi();
};
this.sayBye = function() {
console.log("Goodbye " + this.name);
};
};
var blake = new Person();
blake.callSayHi();
In the case of the callSayHi()
function, the context is the object that invoked callSayHi()
, or blake
. So, the definition of this
is the instance of Person
called blake
and the console outputs the following:
O hai, my name is Blake
Next, the sayHi()
function gets called. At this point, I would assume that this
would refer to blake
again but the console says otherwise with some unexpected behavior:
Salutations. My name is result
Next, I try setting the mystery this
reference and log to the console again:
Salutations. My name is Jon
At this point, however, I still don't know what this
refers to, just that I've assigned a property on it and that that property had an old value of result
.
Finally, to check if this
does refer to blake
, I call sayBye()
, which gives me an error:
Uncaught TypeError: undefined is not a function
So I know that this
does not refer to blake
in the context of sayHi()
; what does this
refer to, then? Does it refer to sayHi
(narrower scope) or does it refer to the window
(broader scope)?
Is there any way for me to declare a function who's context is Person
that does not get explicitly assigned to a property (similar to a "private" function in languages like Java)?
Finally, a much more general question: if this
refers to the window
in my first question, how does the definition of this.name
not bind to sayHi
, and instead, binds to window
? I made a function called Person
and this
refers to Person
in that context, but when I make a function sayHi
, this
refers to window
...? Is it because sayHi
was defined as:
var sayHi = function() { ... }
...and not:
function sayHi() { ... }
?