What happened?
I expected you to use the function object when you used new, but you returned an object.
-->return{
init:init,
b:function(){
return b;
},
a:a,
c:c
}
Usually new isn't used when an object is being returned. When this happens, the context of the function object is lost, as a result, this is what the returned object's init function looks like
function(d,e,f)
{
a=d;
b=e;
c=f;
};
with literally no reference to anything else. At this point you are in a global scope (unless bind was used which is a different issue) causing a,b, and c to now be defined globally (assuming strict is not being used). So what this accomplishes is to create 3 global variables and then assign them to the values.
As a result, this is what ends up happening in your calls at the very end.
You first start by assigning the three global variables a,b, and c to 1,2, and 3
instobj.init(1,2,3);
Next, you alert the value of a, which was still referenced by your returned object, and took a value from the constructor of 4. As a result 4 is alerted
alert(instobj.a); //display 4 (because that came from the constructor)
In the following line, you reference a function which has no context and as a result is referencing global scope. The variable it returns is the global variable b
, set above with init to 2
alert(instobj.b()); //display 2 (this returned b, a global variable)
The last call is to c. However, c is still referencing the original function object's variable c, and that was only declared once but never assigned to. (remember? var b,c;
. If this were var a,c=-1;
then the following code would alert -1).
alert(instobj.c); //display nothing (undefined from var b,c;)
What could be changed?
Usually a prototypal approach is taken in javascript. This means you set up a constructor, define some prototype functions that each instance will use, and then new up instances of those. For your testobj, that would look like this:
function Test(x){
this.a = x;
this.b = undefined;
this.c = undefined;
}
Test.prototype.init = function(d,e,f){
this.a = d;
this.b = e;
this.c = f;
};
When new is used, this
refers to the instance of the function object. Later, when referencing the variable the instantiation was assigned to, the .
property name may be used to reference this.
property values.
Also when new is used, functions attached to the prototype are included in the instantiated object. Their scope is the same this
as described above, and the property references will be the same as well.
As a result, you may access your test object like this:
var testobj = new Test(4);
testobj.init(1,2,3);
alert(testobj.a);//1
alert(testobj.b);//2
alert(testobj.c);//3
jsFiddle Demo
Link to top of answer