Inheritance in Javascript question

R

Robert

Hi!

So far I have been doing "inheritance" in Javascript like this:

******
function TestObject(value)
{
this.value = value;
}

function ExtendedObject(value1, value2)
{
TestObject.call(this, value1);
this.value2 = value2;
}

ExtendedObject.prototype = new TestObject();
******

This works okay, but I have a wrong feeling with the TestObject
constructor being called just to "inherit" from it and a second time
again later. Especially if the TestObject function really expected a
value parameter. Is there a way so I can "inherit" without doing
ExtendedObject.prototype = new TestObject();

I looked at http://www.crockford.com/javascript/inheritance.html
but the constructor is called twice in that framework too.
 
V

VK

Robert said:
Hi!

So far I have been doing "inheritance" in Javascript like this:

******
function TestObject(value)
{
this.value = value;
}

function ExtendedObject(value1, value2)
{
TestObject.call(this, value1);
this.value2 = value2;
}

ExtendedObject.prototype = new TestObject();
******

This works okay, but I have a wrong feeling with the TestObject
constructor being called just to "inherit" from it and a second time
again later. Especially if the TestObject function really expected a
value parameter. Is there a way so I can "inherit" without doing
ExtendedObject.prototype = new TestObject();

Well, you may decide first what kind of inheritance you want to use -
because the above looks like a holly cocktail of both methods :)

Either you have a set of independent constructors extending and
inheriting each other in any defined way (what is what called
"parasiting inheritance" in one article I read which is a sure way for
a heart attack for C/Java programmers :)

Or you are patching the prototype chain of a single constructor until
it starts producing needed objects.

I see no reason to use both ways at once - unless you want to
complicate your own life.
 
R

Robert

VK said:
Well, you may decide first what kind of inheritance you want to use -
because the above looks like a holly cocktail of both methods :)

I don't really see why the above would look like a cocktail, but if you
have a better way please show it. I really don't mind which method it is.
 
L

Lasse Reichstein Nielsen

Robert said:
So far I have been doing "inheritance" in Javascript like this:

******
function TestObject(value)
{
this.value = value;
}

function ExtendedObject(value1, value2)
{
TestObject.call(this, value1);
this.value2 = value2;
}

ExtendedObject.prototype = new TestObject();
******

This works okay, but I have a wrong feeling with the TestObject
constructor being called just to "inherit" from it and a second time
again later.

I concur.

What I would do is to create an object extending from
TestObject.prototype, and use that as ExtendedObject.prototype.
That is kindof what you do, except that the function you use
to create the extending object also initializes the new object.
We don't want that.

So, we create another function with TestObject.prototype and
no other effect, and use that to extend the object. This
is a general operation, so let's make a function that does it:

function clone(object) {
function Dummy(){};
Dummy.prototype = object;
return new Dummy();
}

Then you can do:
ExtendedObject.prototype = clone(TestObject.prototype);

/L
 
R

Robert

Lasse said:
So, we create another function with TestObject.prototype and
no other effect, and use that to extend the object. This
is a general operation, so let's make a function that does it:

function clone(object) {
function Dummy(){};
Dummy.prototype = object;
return new Dummy();
}

Then you can do:
ExtendedObject.prototype = clone(TestObject.prototype);

Looks interesting.
I'm trying hard to understand what happens in this code, but my mind
can't understand it fully.
How is this different compared to directly doing
ExtendedObject.prototype = TestObject.prototype;
?
 
J

John G Harris

Robert said:
Hi!

So far I have been doing "inheritance" in Javascript like this:

******
function TestObject(value)
{
this.value = value;
}

function ExtendedObject(value1, value2)
{
TestObject.call(this, value1);
this.value2 = value2;
}

ExtendedObject.prototype = new TestObject();

Why do you want a prototype that holds data (the value property)? It's
no use to you.

A prototype object is really a different type, so why not give it a
separate constructor :

function ProtoExtendedObject()
{
// Attach method functions here
}

ProtoExtendedObject.prototype = new ProtoTestObject(); // Proto chain


ExtendedObject.prototype = new ProtoExtendedObject();
 
L

Lasse Reichstein Nielsen

Robert said:
Lasse Reichstein Nielsen wrote:

I'm trying hard to understand what happens in this code, but my mind
can't understand it fully.
How is this different compared to directly doing
ExtendedObject.prototype = TestObject.prototype;
?

The difference is that there is another object in the prototype chain.
The prototype chain of the new ExtendedObject is:

[new cloned object]
|
v
[TestObject.prototype]
|
v
[Object.prototype]


You don't use it here, but you could use it to add properties to
ExtendedObject.prototype that is shared by all instances of
ExtendedObject, but is not shared by TestObject instances.

If you just assign TestObject.prototype directly to
ExtendedObject.prototype, you can't add properties to only
ExtendedObject's prototype.

/L
 
M

Michael Winter

Lasse Reichstein Nielsen wrote:
[snip]
function clone(object) {
function Dummy(){};
Dummy.prototype = object;
return new Dummy();
}

Then you can do:
ExtendedObject.prototype = clone(TestObject.prototype);

Looks interesting.
I'm trying hard to understand what happens in this code, but my mind
can't understand it fully.
How is this different compared to directly doing
ExtendedObject.prototype = TestObject.prototype;

If one did what you suggest, then

ExtendedObject.prototype.myProperty = 'value';

would not only change the prototype object for ExtendedObject, but also
that of TestObject as both prototype properties reference, rather than
copy, the same object.

Lasse's code creates a new object specifically for the task of acting as
the prototype object of ExtendedObject. This prevents such interference.

Mike
 
R

Robert

Michael said:
Lasse Reichstein Nielsen wrote:

[snip]
function clone(object) {
function Dummy(){};
Dummy.prototype = object;
return new Dummy();
}

Then you can do:
ExtendedObject.prototype = clone(TestObject.prototype);


Looks interesting.
I'm trying hard to understand what happens in this code, but my mind
can't understand it fully.
How is this different compared to directly doing
ExtendedObject.prototype = TestObject.prototype;


If one did what you suggest, then

ExtendedObject.prototype.myProperty = 'value';

would not only change the prototype object for ExtendedObject, but also
that of TestObject as both prototype properties reference, rather than
copy, the same object.

Thank you! Now it all makes sense :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top