I understand that functions called without the "new" keyword spit out all their properties on to the global context. But I am seeing some curious behavior, with this piece of Javascript code:
function Test3() {
var a=0;
this.inc = function() {
return ++a;
};
this.noInc = function() {
return a;
};
this.testRef = function() {
return this;
};
return {
inc: inc,
testRef: testRef,
noInc: noInc
};
}
var o = Test3(); // Put func properties on global context
var o2 = Test3(); // Put func properties on global context (replacing properties above??)
// Both "o" and "o2" maintain their own copy of "a" (closure)
alert("o: " + o.inc());
alert("o: " + o.inc());
alert("o: " + o.inc()); // Will output 3 (as expected)
alert(noInc()); // Output: 1 (This seems to not be affected by o.inc() calls - expected)
// However...
alert("o2: " + o2.inc());
alert("o2: " + o2.inc());
alert("o2: " + o2.inc());
alert("o2: " + o2.inc()); // Will output 4 (as expected)
alert(noInc()); // Will output 4 (seems to share with o2), but why?
alert(o === window); // false
alert(o.testRef() === o); // true (I thought testRef() would be on global context?)
alert(o.testRef() === window); // false (^^)
alert(o2 === window); // false
alert(o2.testRef() === o2); // true (I thought testRef() would be on global context?)
alert(o2.testRef() === window); // false (^^)
alert(testRef() === window); // true (How come this is here? Look at comments above)
When we call
var o = Test()
, what exactly happens here? What context doesTest()
execute in. Since thenew
keyword is missing, I believe,this
insideTest3()
would refer to window? What does "o" refer to? Is it simply a variable declared on the global context?If above is true, then how are o and o2 able to maintain separate copies of Test3's local variable "a". I understand that we have closure in action here, but then how come, "o2" and "window" share the same copy of the variable "a", but NOT "o"
When I do var o = Test3() and then do alert(o.testRef() === window), it says false. So after executing:
var o = Test3(); var o2 = Test3();
There seems to be 3 copies of the properties from Test3()
. One on "o", another one on "o2" and one on the global context.
But how can there be any on "o" and "o2" - I am not calling Test3()
with the "new" keyword, so this should only refer to global context?
Every time you call
Test3
, theinc
,noInc
andtestRef
functions are reassigned towindow
with a differenta
(which is initialized to0
at the top of the function.)window
ando2
share the samea
because the functions were reassigned towindow
wheno2
got the return value and noto1
.Example from NodeJS REPL (note in NodeJS, the global object is referenced by
global
instead ofwindow
, but otherwise there shouldn't be any difference):Because
Test3
was only called once and set too1
, both the global scope ando1
share ana
. Now watch as I callTest3
again:The functions are reassigned to the global object, with an
a
of0
, whileo
keeps the previousa
.Your code can be reduced to:
So basically you're overriding the definition of
inc
andnoinc
bound to a differenta
.If instead of
var a = 0
you hadthis.a = this.a || 0
you would bind to the samea
.