3

I AM trying to understand js prototype property: my sample code

function Container(param) {
 this.member = param;
}
var newc = new Container('abc');
Container.prototype.stamp = function (string) {
 return this.member + string;
}
document.write(newc.stamp('def'));
function Box() {
 this.color = "red";
 this.member = "why";
}
Container.prototype = new Box();
Box.prototype.test = "whatever";
var b = new Box();
document.write(newc.test);

here the last line is undefined - even though Container's prototype is a Box and Box's prototype has a property test, why is the newc which refers to test in Box doesnt work? can any one please explain how the 'Prototype' works in my above context.

Thanks...

Andreas Köberle
112k58 gold badges281 silver badges308 bronze badges
asked Jul 1, 2011 at 23:47
3
  • 1
    As @The Scrum Meister said, you set the prototype of Container after the instance was created. The instance will still point to the old prototype. Commented Jul 1, 2011 at 23:59
  • You can just comment on answers to your question, you don't have to "edit" the answer. Commented Jul 2, 2011 at 0:26
  • 1
    @FelixKling I don't think you can comment if you have a rating of 1 :s Commented Dec 13, 2011 at 16:28

3 Answers 3

3

You are setting Container prototype to Box() after the newc instance was already created.

Reorder the statements as follows:

function Container(param) {
 this.member = param;
}
function Box() {
 this.color = "red";
 this.member = "why";
}
Container.prototype = new Box();
Box.prototype.test = "whatever";
Container.prototype.stamp = function (string) {
 return this.member + string;
}
//Here the containers prototype setup is complete.
var newc = new Container('abc');
document.write(newc.stamp('def'));
document.write(newc.test);
answered Jul 1, 2011 at 23:54
Sign up to request clarification or add additional context in comments.

1 Comment

I think the example would be better if you define the instance, before you set the Box.prototype.test = "whatever"; attribute. That would make it clearer that the only "problematic" line is Container.prototype = new Box();.
2

If sounds like you want to know WHY it is behaving the way it is, and not just "fix" the code. So here's what's going on.

As you saw, if you change the prototype of "Container", you will actually change the properties for new objects AND objects already instantiated. So:

function Container(param) {
 this.member = param;
}
var newc = new Container('abc');
// setting a new property of the prototype, after newc instantiated.
Container.prototype.stamp = function (string) {
 return this.member + string;
}
// This already-instantiated object can access the stamp function
document.write(newc.stamp('123')); // output: abc123

So there's no problem with the above, as long as you don't call the new method before it's defined. Now the next point. Add this to the above:

// Our Box object
function Box() {
 this.color = "red";
 this.member = "why";
}
Container.prototype = new Box();
var newd = new Container('fgh');
document.write(newd.stamp('456')); // output: ERROR

Error! But that makes sense, right? You totally wiped out the "Container" prototype and replaced it with the one from "Box", which has no "stamp" function.

I am going to assume you want "Box" to inherit from "Container". That would be logical from the naming convention. If you want to do that, replace the previous section with this:

// Our Box object
function Box() {
 this.color = "red";
 this.member = "why";
}
// This inherits from Container. Note that we can
// do this before or after we declare "Box"
Box.prototype = new Container();
Box.prototype.test = "Whatever";
var b = new Box("jkl"); // note: "jkl" is ignored because "Box" sets "member" to "why"
document.write(b.test); // output: Whatever
document.write("<br>");
document.write(b.stamp("345")); // output: why345

So now we have a "Box" that can call its own methods and parameters, and also call them from its parent "Container".

So the big picture is that an object will look at its own prototype for a method or something, and if it doesn't find it there it will look in the prototype of the thing it inherited from, and so on. The other big point is that setting something in the prototype makes it immediately available in all future AND current instances of that object.

answered Aug 24, 2011 at 20:23

2 Comments

You lost me on the last paragraph... In the Box example, the Box's prototype is now Container, right? From your statement, it would appear Box has a prototype, checks it and if its not there then uses the container's prototype.
@justnS, Box initially has its prototype set to an instantiated Container object. That makes Box inherit Container. Then AFTER that, we set further parameters directly in the Box prototype. This will create new parameters or override the ones inherited from Container. Clear as mud?
0

An object does not contain a reference to its constructor which it uses to get at the prototype. If it did, then the code would work as you expected.

Instead, an object contains a reference to its prototype that is set when it is created.

From the language spec section 4.2.1:

Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s "prototype" property. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; this is called the prototype chain. When a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name. In other words, first the object mentioned directly is examined for such a property; if that object contains the named property, that is the property to which the reference refers; if that object does not contain the named property, the prototype for that object is examined next; and so on.

answered Jul 2, 2011 at 0:04

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.