I'm having real trouble getting my head around some fundamental concepts in JavaScript so am hoping someone can give me a good explanation of what is happening under the hood in these examples.
CASE 1:
In this case I use the 'this' keyword in a constructor function:
function Counter() {
    this.c = 0;
    this.incC = function() {
        return this.c++;
    };
}
Obviously now I can instantiate the function and call the incC function to increment c and a record of c will be held in the created instance as the 'this' refers to the actual object being created. Here from my (limited) experience programming in C I imagine that when I do:
var counter = new Counter();
-the code is effectively allocating space for the object and then passing a pointer to that allocated memory into the constructor and that pointer is the 'this'.
But I have to wonder if I'm wrong because in case 2 things are a little different.
CASE 2:
In this function I can create a persistent variable using the 'this' keyword. However, I am not going to instantiate it, so it cannot be pointing to an object and it doesn't seem to be an attribute of counter (obviously the function itself is an object) as counter.c returns undefined.
function counter() {
    this.c = this.c || 1;
    return this.c++;
}
console.log(counter.c); // undefined
So what is happening under the hood in this example? Why and how is c not being lost when we exit the function and what is the 'this' pointing at in this example?
CASE 3:
Finally just to make things more interesting.
I came across this in a very old code base (I know there are more accurate ways to do inheritance but found this example interesting as to how it works exactly):
function CounterChild() {
    Counter();
}
CounterChild.prototype = new Counter();
CounterChild.constructor = CounterChild;
var child = new CounterChild();
console.log(child.c); // 0
Here the this keyword relates to the object being instantiated, but how exactly does the call to the Counter() constructor get passed a reference to the object being created? I mean how does the interpreter know that this function should be passed a pointer at all as the new key word is not being used?
                        
The most important thing to understand about
thisis that its value is determined by how the function called (expect for ES6 arrow functions, wherethisis lexically scoped, and functions that are bound via.bind).Calling
new Counter()is very different from callingCounter()and thusthisrefers to different values.Overall I recommend to read MDN -
thisfor more information aboutthis.Case 1
Yes
Case 2
Since the function is called "normally", i.e. as
foo(),thisrefers to the global object, which iswindowin browsers. The code is equivalent toCase 3
It doesn't. Calling
CounterinsideCounterChild()has no visible effect(*) here and you could simply remove it.The
cproperty comes fromCounterChild.prototype.c, since you assigned aCounterinstance toCounterChild.prototype. You can verify this by inspectingconsole.dir(child).CounterChild.prototypeis the prototype of all instances created throughnew CounterChild(). Any property that does not exist on an object itself is looked up in the object's prototype chain.If you want
thisinsideCounterto refer to the newly created object, you have to pass it explicitly:*: That's actually not true. Just like in case 2, it does change the global variable
c, but that is definitely not what you want.