1

At last there i see a smell of closure in the following code.

function create(parent) {
var F = function() {};
 F.prototype = parent;
return new F();
}
var masterObject = {a: "masterObject value"}
var object1 = create(masterObject);
var object2 = create(masterObject);
var object3 = create(masterObject);
var object3.a = "overridden value";
object1.a; // "masterObject value"
object2.a; // "masterObject value"
object3.a; // "overridden value"
masterObject.a = "new masterObject value"//value is changed now
object1.a; // "new masterObject value"
object2.a; // "new masterObject value"
object3.a; // "overridden value"

the value of object1.a ,abject2.a is changed permamently .Is this because i made a change in global variable or that is the affect of closure?since i have not invoked the Create() function again why is the value changed automatically? last question "when i made a change in global variable does that automatically affect all the object using tht variable?"in my view to make an effect of that variable i should call the Create() function again isn't it?

asked Jan 6, 2013 at 10:16
2

3 Answers 3

3

When you access object3.a, JavaScript first looks at the object's properties. If the object doesn't have a property called a, the object's prototype is checked next.

Setting object3.a = "overridden value"; gives object3 a property called a. It doesn't affect your prototype's a property.

Since object1 and object2 don't have a property called a, but their prototype does, when you modify masterObject's a property, the value changes globally for all objects that have masterObject as their prototype.

Even though you gave object3 a property called a, but you can still access the prototype's a property, which remains the same:

object3.__proto__.a; // "new masterObject value"

Basically, by giving object3 a property called a, you're putting the object's new property "in front" of the prototype's property.

answered Jan 6, 2013 at 10:31
Sign up to request clarification or add additional context in comments.

2 Comments

last question "when i made a change in global variable does that automatically affect all the object using tht variable?"in my view to make an effect of that variable i should call the Create() function again
@MaizerePathak: It's not really a global variable. It's a prototype. Your create() function assigns masterObject to be your object's prototype, so whatever you do to masterObject will affect all objects using it as their prototype.
0

When you alter an object's 'a' property directly (as you do with var object3.a = "overridden value"; (which shouldn't have a var in front of it), you alter that instance's own 'a' property.

So, what really happens is:

object3.a = "overridden value"; here you create a new property on object3. It didn't have an 'a' property before. Its prototype did however, so object3.a was legal and would refer to the prototype's 'a' property.

masterObject.a = "new masterObject value" here you alter the prototype of all objects (created by create()). So if you access the property 'a' on objects, it will now be changed, except for those which have their own 'a' properties (such as object3).

answered Jan 6, 2013 at 10:34

1 Comment

Answering Maizere's question on the comment on Blender's answer: You don't have to change the create() function. Altering the prototype at any moment will directly alter all objects of that type, so to speak. Naturally, they will not be "altered", but they are bound to their prototype, and changes to it are affected immediately.
0

This happens because of how inheritance works in prototype-based languages, such as javascript. When you call create(masterObject), you are returning a new instance of a function object (that you call F) with its prototype set to masterObject. That means that the prototype field for object1, object2, and object3 point to the same object, masterObject.

The statement:

object3.a = "overriden value"

creates a field called a in object3 and assigns it the string "overriden value", and thats what you get when you examine object3.a. But when you look at object1.a, the interpreter notices that the a field does not exist in object1 so it follows the prototype link to its parent and examines that for a field called a. In this case, the prototype link points to masterObject which has a field called a that holds the string "masterObject value" and thats what you see. If masterObject did not have a field called a, the interpreter would follow the prototype link again and again until it finds an a field or until it reaches an object with an empty prototype link and it will then return the value undefined.

So by changing masterObject.a, you change what you see when you examine object1.a and object2.a because object1 and object2 do not have a field called a, so they "inherit" it from their parent, masterObject.

This does not happen when you examine object3.a because you created a field called a in object3 that holds the string "overridden value".

If, at the end of your code, you add:

delete object3.a;

you would now see "new masterObject value" when you look at object3.a, because object3 no longer has a field called a, so it "inherits" it from its parent, masterObject.

answered Jan 6, 2013 at 10:49

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.