473,573 Members | 2,686 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Inheritance using object prototype

Hi all - I'm preparing to dive in to more complex application
development using javascript, and among other things, I'm having a hard
time wrapping my head around an issues regarding "inheritanc e" using
the prototype property. I realize there are no classes in JS, that code
therefore lives in objects instead of class definitions, and that
"inheritanc e" must be achieved prototypically and not classically.
That said, on with the code. Say I have an object I wish to use as a
super type:

function SuperA(name) {
this.name = name;
this.alertName = function() { alert(this.name ); }
}

It takes a string in the constructor, assigns it to the name property,
and provides a way to display that name in an alert box, via alertName
method. What I've come to learn is that if I want to create a sub type,
I must assign a new instance of the super type to the prototype of the
sub type. Like so:

function SubA(name) {
//sub type properties
}
SubA.prototype = new SuperA();

This works fine in that when I create an instance of SubA, it
effectively inherits everything from SuperA. What I don't understand is
why this doesn't achieve the same effect:

function SubA(name) {
this.prototype = new SuperA(name);
}

This simply assigns an instance of the super type to the prototype of
the sub type instance in construction, yet if I create an instance and
attempt to call the method:

var supa = new SubA('one');
supa.alertName( );

I get a JS error stating that supa.alertName is not a function. Note
that if I augment the the latter constructor to show the memebers in
construction:

function SubA(name) {
this.prototype = new SuperA(name);
for(var m in this.prototype) {
alert(m + ": " + typeof(this.pro totype[m]) + ": " +
this.prototype[m]);
}
}

I get two alerts; the first being:

name: string: one

and the second:

alertName: function: function() { alert(this.name ); }

I'd appreciate any clarity that is offered. Thanks!

Jan 12 '07 #1
6 1863
VK
burningodzi...@ gmail.com wrote:
Hi all - I'm preparing to dive in to more complex application
development using javascript, and among other things, I'm having a hard
time wrapping my head around an issues regarding "inheritanc e" using
the prototype property.
The first thing you have to do is to read and study
"The JScript Type System, Part Two: Prototypes and constructors"
<http://blogs.msdn.com/ericlippert/archive/2003/11/06/53352.aspx>
by Eric Lippert

Up to date this is the only existing online resource where inheritance
in ECMAScript languages explained both correctly and understandably.
I really don't want to spoil the reading :-) but your current problem
arose from the fact that .prototype property _does not_ define
prototype chain for the object it is applied to. It defines prototype
chain for _instances_ created by the given constructor. Search for the
rest in the linked article.

Besides that two other considerations to take into account:
1) Programming in javascript doesn't mean "use prototype only".
Inherited properties and methods are static in Cx sense: it means that
for 100 object instances there will be only one method if it is
inherited over prototype chain. It means that prototype inheritance is
useful only for members where you don't need to store instance-specific
data. If you need members with instance-specific data then use
constructor itself.

2) Code like
function f() {
this.m = function(){aler t('Hello');}
}
forms a closure on each invocation. You don't want to form a closure
unless you _want_ to form a closure.

Jan 12 '07 #2

burningodzi...@ gmail.com wrote:
Hi all - I'm preparing to dive in to more complex application
development using javascript, and among other things, I'm having a hard
time wrapping my head around an issues regarding "inheritanc e" using
the prototype property. I realize there are no classes in JS, that code
therefore lives in objects instead of class definitions, and that
"inheritanc e" must be achieved prototypically and not classically.
That said, on with the code. Say I have an object I wish to use as a
super type:

function SuperA(name) {
this.name = name;
this.alertName = function() { alert(this.name ); }
}

It takes a string in the constructor, assigns it to the name property,
and provides a way to display that name in an alert box, via alertName
method. What I've come to learn is that if I want to create a sub type,
I must assign a new instance of the super type to the prototype of the
sub type. Like so:

function SubA(name) {
//sub type properties
}
SubA.prototype = new SuperA();

This works fine in that when I create an instance of SubA, it
effectively inherits everything from SuperA. What I don't understand is
why this doesn't achieve the same effect:

function SubA(name) {
this.prototype = new SuperA(name);
}

This simply assigns an instance of the super type to the prototype of
the sub type instance in construction, yet if I create an instance and
attempt to call the method:

var supa = new SubA('one');
supa.alertName( );

I get a JS error stating that supa.alertName is not a function. Note
that if I augment the the latter constructor to show the memebers in
construction:

function SubA(name) {
this.prototype = new SuperA(name);
for(var m in this.prototype) {
alert(m + ": " + typeof(this.pro totype[m]) + ": " +
this.prototype[m]);
}
}

I get two alerts; the first being:

name: string: one

and the second:

alertName: function: function() { alert(this.name ); }

I'd appreciate any clarity that is offered. Thanks!
Hi

Three points:-

1. In very simple terms, the "prototype" property used for inheritance
must usually be property of the Function you are using as a constructor
function.

When you create an Object with "new SubA", the Object you create does
not itself does not itself give you express access to the "prototype"
used in the inheritance chain through a "prototype" property.

Having said that, in Firefox (and perhaps other browsers, excluding IE)
you can access this prototype through the "__proto__" property. See :
http://www.webreference.com/js/column79/6.html

2. When you when you call "new SubA", the "this" value refers to the
Object you are creating, not the SubA Function.

So

"this.proto type = new SuperA(name);"

effectively creates a new dynamic property, called "prototype" , on your
Object; but which has nothing to do with the prototype used in the
inheritance chain.

3. I have no idea what would happen if you called "this.__pro to__ =
new SuperA(name)".

Regards

Julian Turner

Jan 12 '07 #3
Thanks for the info - it has been very helpful. VK I digested the
article you liked - it was also quite illuminating - much appreciated.
I have a comment regarding one of your points:
Inherited properties and methods are static in Cx sense: it means that
for 100 object instances there will be only one method if it is
inherited over prototype chain. It means that prototype inheritance is
useful only for members where you don't need to store instance-specific
data. If you need members with instance-specific data then use
constructor itself.
That doesn't seem to be entirely correct - at least not the part about
static in a Cx sense. If I declare a super type with two methods on the
Function:

function SuperA() {}
SuperA.getName = function() { return this.name; }
SuperA.setName = function(n) { this.name = n; }

and then a sub type with this as its prototype:

function SubA(n) {
this.name = typeof(n) == 'undefined' ? '' : n;
}
SubA.prototype = SuperA;

var supa = new SubA('test 1-1');
alert(supa.getN ame());
supa.setName('t est 1-2');
alert(supa.getN ame());

var supa2 = new SubA('test 2-1');
alert(supa2.get Name());
supa2.setName(' test 2-2');
alert(supa2.get Name());
//verify that 2 different instances have unique data and thus unique
members
alert(supa.getN ame());

Then the inherited methods act on the instance data, since the methods
access this.name. So in that since they differ from static methods as
they can indeed access instance data (I confirmed creating multiple
instances have unique members). If however the methods are declared
without accessing this.x:

function SuperA() {
this.name = 'super';
}
SuperA.getName = function() { return name; }
SuperA.setName = function(n) { name = n; }

Then the methods all access the singular name property of the SuperA
constructor.

Point being that methods inherited on the prototype chain can access
instance data via this.

Regarding your point on closures - I incorrectly (due to my oo
background) assumed that declaring methods like that would pass them on
to inheriting types. As you pointed out, only members on the Function
prototype get propagated. However it seems that adding methods to the
Function prototype that access instance members via this is a workable
way to pass on methods sub types. Are you under this impression?

Thanks again for the discussion and info!

VK wrote:
burningodzi...@ gmail.com wrote:
Hi all - I'm preparing to dive in to more complex application
development using javascript, and among other things, I'm having a hard
time wrapping my head around an issues regarding "inheritanc e" using
the prototype property.

The first thing you have to do is to read and study
"The JScript Type System, Part Two: Prototypes and constructors"
<http://blogs.msdn.com/ericlippert/archive/2003/11/06/53352.aspx>
by Eric Lippert

Up to date this is the only existing online resource where inheritance
in ECMAScript languages explained both correctly and understandably.
I really don't want to spoil the reading :-) but your current problem
arose from the fact that .prototype property _does not_ define
prototype chain for the object it is applied to. It defines prototype
chain for _instances_ created by the given constructor. Search for the
rest in the linked article.

Besides that two other considerations to take into account:
1) Programming in javascript doesn't mean "use prototype only".
Inherited properties and methods are static in Cx sense: it means that
for 100 object instances there will be only one method if it is
inherited over prototype chain. It means that prototype inheritance is
useful only for members where you don't need to store instance-specific
data. If you need members with instance-specific data then use
constructor itself.

2) Code like
function f() {
this.m = function(){aler t('Hello');}
}
forms a closure on each invocation. You don't want to form a closure
unless you _want_ to form a closure.
Jan 12 '07 #4
In article <11************ **********@a75g 2000cwd.googleg roups.com>,
bu************@ gmail.com writes

<snip>
>What I've come to learn is that if I want to create a sub type,
I must assign a new instance of the super type to the prototype of the
sub type. Like so:

function SubA(name) {
//sub type properties
}
SubA.prototy pe = new SuperA();
<snip>

I'm afraid you've learnt a messy way of doing it.

Suppose you have three constructors A, B, and C, and you want C
instances to derive from B and B from A. When you create a C instance by
doing

var cobj = new C(x, y, z);

you want cobj to have a prototype chain holding all the methods of A, B,
and C objects, and cobj itself to hold all the data fields appropriate
to A, B, and C objects. In javascript you, yourself, have to do the work
of making this happen :-(

The job of the objects in the prototype chain is to hold methods, not
data. To do it cleanly you don't want these objects to be A, B, or C
instances : they are different types. You could call them proto_A,
proto_B, and proto_C instances, and construct them with their own
special constructors.

John
--
John Harris
Jan 12 '07 #5
Hi John - thanks for the comments. Thus far I've learned what you said,
and have been assigning Function definitions (as opposed to instances)
to prototypes of sub types. The one thing that I haven't found that
you've said is that for each instance you must create all it's data
members in the constructor. Following is a snip of code I've been
documenting for my learning purposes - please tell me if feel my
findings are invalid:

function SuperA() {
/*
* Any members defined here will be available to instances created
* via new SuperA(). They are object instance members, NOT Function
* members, and therefore will not be added into the prototype chain
* when SuperA is set as the prototype of other Functions (sub types).
*/
}
/*
* These methods access this.name, and so access the member name
* in the context of the current object instance. This seems to
* effectively allow sub types to inherit these methods and have
* them operate on their instance members.
*
* Note that if a sub type doesn't explicitly declare a this.name
* member in its constructor, the memeber will be undefined. Calling
* [instance].setName on the instance will add this member to it.
*/
SuperA.getName = function() { return this.name; }
SuperA.setName = function(n) { this.name = n; }
/*
* Note that the data member (sname) declared as a Function member of
* SuperA will be propagated to sub type instances. Each sub type
instance
* will have it's own copy (at least of the sname data member), as
proven
* below.
*/
SuperA.sname = 'super';
SuperA.getSname = function() { return this.sname; }
Lastly, regarding your statment:
The job of the objects in the prototype chain is to hold methods, not
data. To do it cleanly you don't want these objects to be A, B, or C
instances : they are different types. You could call them proto_A,
proto_B, and proto_C instances, and construct them with their own
special constructors.
Would you mind providing a simple example?

Much apperciated!
John G Harris wrote:
In article <11************ **********@a75g 2000cwd.googleg roups.com>,
bu************@ gmail.com writes

<snip>
What I've come to learn is that if I want to create a sub type,
I must assign a new instance of the super type to the prototype of the
sub type. Like so:

function SubA(name) {
//sub type properties
}
SubA.prototype = new SuperA();
<snip>

I'm afraid you've learnt a messy way of doing it.

Suppose you have three constructors A, B, and C, and you want C
instances to derive from B and B from A. When you create a C instance by
doing

var cobj = new C(x, y, z);

you want cobj to have a prototype chain holding all the methods of A, B,
and C objects, and cobj itself to hold all the data fields appropriate
to A, B, and C objects. In javascript you, yourself, have to do the work
of making this happen :-(

The job of the objects in the prototype chain is to hold methods, not
data. To do it cleanly you don't want these objects to be A, B, or C
instances : they are different types. You could call them proto_A,
proto_B, and proto_C instances, and construct them with their own
special constructors.

John
--
John Harris
Jan 12 '07 #6
In article <11************ *********@38g20 00cwa.googlegro ups.com>,
chrislewis <bu************ @gmail.comwrite s
>Hi John - thanks for the comments. Thus far I've learned what you said,
and have been assigning Function definitions (as opposed to instances)
to prototypes of sub types. The one thing that I haven't found that
you've said is that for each instance you must create all it's data
members in the constructor. Following is a snip of code I've been
documenting for my learning purposes - please tell me if feel my
findings are invalid:

function SuperA() {
/*
* Any members defined here will be available to instances created
* via new SuperA(). They are object instance members, NOT Function
* members, and therefore will not be added into the prototype chain
* when SuperA is set as the prototype of other Functions (sub types).
*/
}
/*
* These methods access this.name, and so access the member name
* in the context of the current object instance. This seems to
* effectively allow sub types to inherit these methods and have
* them operate on their instance members.
*
* Note that if a sub type doesn't explicitly declare a this.name
* member in its constructor, the memeber will be undefined. Calling
* [instance].setName on the instance will add this member to it.
*/
SuperA.getNa me = function() { return this.name; }
SuperA.setNa me = function(n) { this.name = n; }
/*
* Note that the data member (sname) declared as a Function member of
* SuperA will be propagated to sub type instances. Each sub type
instance
* will have it's own copy (at least of the sname data member), as
proven
* below.
*/
SuperA.sname = 'super';
SuperA.getSnam e = function() { return this.sname; }
To tell the truth, I'm not sure what you are trying to say here. Have
you tried drawing a picture of an instance and its prototype chain? Show
where you would like to put the things that are common to all instances,
e.g methods, and where you would like to put the things that can be
different in each instance, e.g data values.

If you have put the same thing in lots of different places, or have
things that are never going to be used, then you've done it in a messy
way.

>Lastly, regarding your statment:
>The job of the objects in the prototype chain is to hold methods, not
data. To do it cleanly you don't want these objects to be A, B, or C
instances : they are different types. You could call them proto_A,
proto_B, and proto_C instances, and construct them with their own
special constructors.

Would you mind providing a simple example?
<URL:http://www.jgharris.de mon.co.uk/jsfeats/JSfeats.html#se ca1p1>

John
--
John Harris
Jan 13 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
1655
by: Robert Spoons | last post by:
Can you look over this code, preferably try it, and comment? I believe the 'extend' function below will allow you to use full 'class inheritance' in javascript, but I would like to verify it. The extend function allows the following: 1) inheriting from multiple classes, 2) inheriting an inherited classes inheritances (awkward to say), 3)...
2
3020
by: stephane | last post by:
Hi all, What I am trying to achieve is an 'inherits' method similar to Douglas Crockford's (http://www.crockford.com/javascript/inheritance.html) but that can enable access to the superclass' priviledged methods also. Do you know if this is possible ? In the following example, I create an ObjectA (variable a), an ObjectB which inherits...
2
6313
by: Kevin Newman | last post by:
I have been playing around with a couple of ways to add inheritance to a JavaScript singleton pattern. As far as I'm aware, using an anonymous constructor to create a singleton does not allow any kind of inheritance: singletonObj = new function() { this.prop = true; } Here are two ways to create a singleton with inheritance:
31
1913
by: John W. Kennedy | last post by:
I quite understand about prototypes and not having classes as such, but I happen to have a problem involving blatant is-a relationships, such that inheritance is the bloody obvious way to go. I can think of several ad-hoc ways to achieve inheritance, but is there an accepted standard idiom? -- John W. Kennedy "But now is a new thing which...
14
1483
by: petermichaux | last post by:
Hi, Hopefully the group doesn't mind an(other) inheritance question. Maybe the prototype inheritance style is starting to become a low dim light in my brain...probably not yet. ---- If I do the following...
36
2685
by: Pacific Fox | last post by:
Hi all, haven't posted to this group before, but got an issue I can't work out... and hoping to get some help here ;-) I've got a base object that works fine with named arguments when called on it's own. However when I call the child object I get an error " has no properties (in firefox)." I simple test:
3
2105
by: linc | last post by:
I am planning on writing a fairly large system in javascript and would like some advice on using the Douglas Crockford 'beget' function to implement prototypal inheritance. Searching the internet there don't seem to be any practical examples of javascript prototypal inheritance (or maybe I can't find them). As a start I have created the...
6
14865
by: howa | last post by:
Consider example: Animal = function(age) { this.age = age; }; Animal.prototype.sleep = function() { alert("Animal Sleeping..."); };
6
1443
by: vwkng1987 | last post by:
Hi everyone Please look at the code below: (I am picking up JS from Crockfold and a few other online sources too) *************************************************************** function Employee(name){ this.name = name || 'default'; } function WorkerBee(name, dept){
0
7668
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8179
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7736
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
8036
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5556
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5258
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
1
2167
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1269
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
999
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.