By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,949 Members | 884 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,949 IT Pros & Developers. It's quick & easy.

Inheritance?

P: n/a
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 is very old--
that the rich make themselves richer and not poorer,
which is the true Gospel, for the poor's sake."
-- Charles Williams. "Judgement at Chelmsford"
Jan 19 '06 #1
Share this Question
Share on Google+
31 Replies


P: n/a
VK

John W. Kennedy wrote:
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?


By my humble mind the "is-a" inheritance idiom is the same: you're
using A to make B, B to make C etc. ad infinitum. But I'm ready to
accept that there is some other definitions.

<html>
<head>
<title>Inheritance</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">

<script type="text/javascript">

// ! Important: C in function names
// stays from "constructor", not "class"
// ;-)

function C1() {
C2.call(this);
this.C1_method = function(s){alert(s);};
}

function C2() {
C3.call(this);
this.C2_method = function(s){alert(s);};
}

function C3() {
this.C3_method = function(s){alert(s);};
}

function test() {
var obj1 = new C1();
var obj2 = new C2();
var obj3 = new C3();
alert (obj1 instanceof C1);
alert (obj2 instanceof C2);
alert (obj3 instanceof C3);
}

window.onload = test;
</script>

</head>

<body>

</body>
</html>

Jan 19 '06 #2

P: n/a
"John W. Kennedy" <jw*****@attglobal.net> writes:
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.
It's an is-a relationship between concepts in your domain model?
I can think of several ad-hoc ways to achieve inheritance, but is
there an accepted standard idiom?


In prototypical language, an object is defined by its properties, not
its class. In particular, its methods are important, since updating an
object's properties happens on the object itself, not its prototypes.

I would make sure to have prototype objects separated from working
objects. I.e., something like (really braindead example domain):
---
function Car(name) {
if (name) { this.name = name; }
}
Car.prototype.getName = function getName() { return this.name; };
Car.prototype.setName = function setName(name) { this.name = name; };
Car.prototype.hasName = function hasName(name) { return "name" in this; };

function Convertible() { this.color = "red"; /*great default!*/ }
Convertible.prototype = clone(Car.prototype);
Convertible.prototype.constructor = Convertible;
Convertible.prototype.getColor =
function getColor() { return this.color; };
Convertible.prototype.setColor =
function setColor(color) { this.color = color; };
---
(where clone is defined as:
function clone(obj) {
function cloner(){};
cloner.prototype=obj;
return new cloner();
}
i.e., it creates a new object with the argument as its prototype)

You have the prototypes Car.prototype and Convertible.prototype, where
the latter has the former in its prototype chain. That means that any
dynamic change to Car.prototype will also be visible in objects
created from Convertible - they are cars.

Notice that the prototype of Convertible is not a car (well,
technically it might be since it has Car.prototype in its chain, but
it should not be seen as one), it is just a prototype object
inheriting the properties of Car's prototype.

Prototype objects contain no data, only methods. The data should be
put in the new objects created from these (e.g., through the
constructor).

You could consider calling the Car constructor from the Convertible,
but you would have to have a name available then, e.g.:

function Convertible2(name, color) {
Car.call(this, name);
this.color = color;
}
Well, that would be my approach. If it happens to be a standard idiom,
I guess I picked wisely, but it's not because I knew it :)

However, Javascript is not the first prototype based language. You
could look for what people have done in other languages, e.g., Self.
<URL:http://en.wikipedia.org/wiki/Prototype-based_programming>

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jan 19 '06 #3

P: n/a
In article <bV************@fe08.lga>, John W. Kennedy
<jw*****@attglobal.net> writes
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?


One of the problems with javascript is that there's usually more than
one way to do it, whatever 'it' might be :-(

Myself, I prefer to do inheritance the direct way by building a
prototype chain of objects, as demonstrated in
<URL:http://www.jgharris.demon.co.uk/jsfeats/JSfeats.html#seca1p1>

John
--
John Harris
Jan 19 '06 #4

P: n/a
Lasse Reichstein Nielsen wrote:
Prototype objects contain no data, only methods. The data should be
put in the new objects created from these (e.g., through the
constructor).


It should be pointed out that they contain no non-function properties in
_your example_ object model. However, having such properties on prototypes
can turn out to be useful; as I explained earlier, they provide for default
values of properties of objects that have that prototype object in their
prototype chain.
PointedEars
Jan 20 '06 #5

P: n/a
Lasse Reichstein Nielsen wrote:
"John W. Kennedy" <jw*****@attglobal.net> writes:
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.
It's an is-a relationship between concepts in your domain model?
Assuming that "domain" means "problem domain", yes. Textbook case.
I can think of several ad-hoc ways to achieve inheritance, but is
there an accepted standard idiom?

In prototypical language, an object is defined by its properties, not
its class. In particular, its methods are important, since updating an
object's properties happens on the object itself, not its prototypes. I would make sure to have prototype objects separated from working
objects. I.e., something like (really braindead example domain):
---
function Car(name) {
if (name) { this.name = name; }
}
Car.prototype.getName = function getName() { return this.name; };
Car.prototype.setName = function setName(name) { this.name = name; };
Car.prototype.hasName = function hasName(name) { return "name" in this; };

function Convertible() { this.color = "red"; /*great default!*/ }
Convertible.prototype = clone(Car.prototype);
Convertible.prototype.constructor = Convertible;
Convertible.prototype.getColor =
function getColor() { return this.color; };
Convertible.prototype.setColor =
function setColor(color) { this.color = color; };
---
(where clone is defined as:
function clone(obj) {
function cloner(){};
cloner.prototype=obj;
return new cloner();
}
i.e., it creates a new object with the argument as its prototype)

You have the prototypes Car.prototype and Convertible.prototype, where
the latter has the former in its prototype chain. That means that any
dynamic change to Car.prototype will also be visible in objects
created from Convertible - they are cars.

Notice that the prototype of Convertible is not a car (well,
technically it might be since it has Car.prototype in its chain, but
it should not be seen as one), it is just a prototype object
inheriting the properties of Car's prototype.

Prototype objects contain no data, only methods. The data should be
put in the new objects created from these (e.g., through the
constructor).

You could consider calling the Car constructor from the Convertible,
but you would have to have a name available then, e.g.:

function Convertible2(name, color) {
Car.call(this, name);
this.color = color;
}
Well, that would be my approach. If it happens to be a standard idiom,
I guess I picked wisely, but it's not because I knew it :)
This looks workable, and is just the kind of thing I need.
However, Javascript is not the first prototype based language. You
could look for what people have done in other languages, e.g., Self.
<URL:http://en.wikipedia.org/wiki/Prototype-based_programming>


Yes, that helps, too.

Thank you.

--
John W. Kennedy
"But now is a new thing which is very old--
that the rich make themselves richer and not poorer,
which is the true Gospel, for the poor's sake."
-- Charles Williams. "Judgement at Chelmsford"
Jan 21 '06 #6

P: n/a
Lasse Reichstein Nielsen wrote:
"John W. Kennedy" <jw*****@attglobal.net> writes:
I would make sure to have prototype objects separated from working
objects. I.e., something like (really braindead example domain):
---
function Car(name) {
if (name) { this.name = name; }
}
Car.prototype.getName = function getName() { return this.name; };
Car.prototype.setName = function setName(name) { this.name = name; };
Car.prototype.hasName = function hasName(name) { return "name" in this; };

function Convertible() { this.color = "red"; /*great default!*/ }
Convertible.prototype = clone(Car.prototype);
Convertible.prototype.constructor = Convertible;
Convertible.prototype.getColor =
function getColor() { return this.color; };
Convertible.prototype.setColor =
function setColor(color) { this.color = color; };
---
(where clone is defined as:
function clone(obj) {
function cloner(){};
cloner.prototype=obj;
return new cloner();
}
i.e., it creates a new object with the argument as its prototype)


The above provides a good perspective and insight into Javascript
object construction, and demonstrates a way in which the object model
can be effectively utilized. It's noted as well that it also
illustrates, through the necessity of introduction of the 'clone'
function, one of the fundamental problems, or deficiencies, with the
Javascript language as it currently exists.

Whereas the hierarchical nature of the object model as a mechanism for
provision of prototype inheritance under Javascript is truly quite
wonderful, the facilities provided by the language for manipulation of
the nodes within that structure leave something to be desired. That is,
at least, in my finding.

Why is that? Well, in the development of the object model structure
under program control, everything fundamentally depends on doing
extents from the level above. However, there is a single facility
(ignoring object literals) provided for creating the extensions - the
'new' operator in combination with a so-called 'constructor' function -
that is if not a convoluted mechanism, it is at a minimum an obtuse
mechanism, that fails to present within an object-oriented paradigm.
Not only in the computing sense, but in the literal sense as well.

One contribution to the problem is that the focus is placed almost
entirely on the constructor function. The constructor function, in its
reality, is just a trailing operation to the creation process that
massages and shapes the newly created and delivered object into its
initial (class) form, with that massaging operation occurring
immediately following instantiation of the object into its program
accessible existence. The object's lineage has already been cast by the
time the constructor function is called by having the prototype chain
link imbedded internally in the object by the underlying object
creation process. And where did it get that linkage? -- it was either
pre-assigned within the constructor function object, or attached to the
constructor function through foresightful, anticipatory, program
assignment. Not exactly an intuitive, straightforward mechanism.

So really what's been accomplished by the time you wade through all
this is that an extent has been created from the parent level to the
new object, which in turn has received a final massaging by a function,
which (most unfortunately [1], in my view) is designated 'the
constructor'.

In general, provision of capability to create an extent based on being
in possession of an object reference would be preferable. In the case
of Lasse's example above, that would take the form of:

Convertible.protototype = Car.prototype.extend();

If a trailing massaging, or cultivating, operation is required in the
process of creating the descendant extent, as it most often is, that
would be done as:

oDescendant = o.extend(cFcn, arg1, arg2, ...);

That places the emphasis on the object which provides the underlying
construct of the new object where it really belongs, on the inheritance
it will receive. The 'constructor' function plays the same role as
always, but only as seen to be a finishing operation upon the
instantiation of the newly created object.

With appropriate linkages held in the object, it would be possible then
to extend objects with descendants (which includes
replication/cloning[1-a] - o.parent.extend(..)) in a way that would be,
in my view, much more natural and understandable[2].

While the above doesn't exactly pay great homage to the facilities
fundamentally provided within the language, it is to the credit of
Javascript, that it is possible to add such facility by way of
Object.prototype. That would be to include an Object.prototype.extend
consisting basically of the 'clone' function provided by Lasse above,
and with the addition of an invocation of 'cFcn' by way of Function's
built-in 'call'.

However, in a way that's similarly surprising, adding object capability
through extension of the Object.prototype, introduces a secondary
problem inherent in the language. In doing so, the sole provision for
object iteration by property, the 'for( var iterator in object)'
construct delivers values which then, in many cases, require filtering
through the 'hasOwnProperty' built-in function. This is an unfortunate
consequence that prevents widespread adoption of any enhancements to
the language through inheritance-modification to the top-level object
structure.

This too, once again with respect to the prototyping capability of the
language, along with availability closures, is something for which
compensating functionality can be adequately supplied.

____________

[1] Terminology is important. It appears that 'constructor' as a term
in Javascript has been borrowed from other OO languages without
ensuring that the term really continues to appropriately apply (if it
ever did). The real 'constructor' is the 'new' operation process which
delivers a new object and hooks it into the prototype chain. One
possible alternative for that which is currently termed 'constructor'
would be 'cultivator', to more closely describe the action that
actually occurs. Objects delivered under the application of the
'cultivator' would logically be 'cultivars'. (And I suppose then, a
group of cultivars, which were it not for their subsequent flexible
mutability, might be called a 'cult' ;-)).

[1-a] The designation of 'clone' by Lasse in the creation of a
descendant doesn't really seem to fit. Not in the sense that a clone is
created through delivery of identical genetic material to a physically
independent entity. The term 'clone' seems to be much more applicable
to a sibling replication than to a dependent descendant (ie., the kid,
that it appears, may never leave home ;-)).

[2] as is node construction/manipulation in the DOM.

.../rh

Jan 22 '06 #7

P: n/a
ro********@gmail.com writes:

One contribution to the problem is that the focus is placed almost
entirely on the constructor function. The constructor function, in its
reality, is just a trailing operation to the creation process that
massages and shapes the newly created and delivered object into its
initial (class) form, with that massaging operation occurring
immediately following instantiation of the object into its program
accessible existence.
The main problem, to me, with the focus on the constructor rather than
the creation of the new object with a prototype, is that it looks like
class based thinking, not prototype based. It is actually fairly close
to Java, where the creation of the new object is also performed by the
"new" operator, and the constructors merely initialize the created
object afterwards.
The object's lineage has already been cast by the time the
constructor function is called by having the prototype chain link
imbedded internally in the object by the underlying object creation
process. And where did it get that linkage? -- it was either
pre-assigned within the constructor function object, or attached to
the constructor function through foresightful, anticipatory, program
assignment. Not exactly an intuitive, straightforward mechanism.
It was assigned when the object was created, by the inherent
[[Constructor]] method on all user function objects. That method was
called by the evaluation of the "new" operator expression.

I don't necessarily think it's such a bad idea to have constructor
methods. It looking like class based programming on the surface
probably did a lot to get Javascript popular in the beginning. I'm
just missing a direct approach to prototype based programming, e.g.,
the clone method that other prototype based languages have.
In general, provision of capability to create an extent based on being
in possession of an object reference would be preferable. In the case
of Lasse's example above, that would take the form of:

Convertible.protototype = Car.prototype.extend();
In other prototype based languages (ok, I have only really read a
little on Self), that would be
... Car.prototype.clone()
That would be the traditional name. I can see that "extend" is more
fitting for the operation.
[Object.prototype extension fouls iteration] This too, once again with respect to the prototyping capability of the
language, along with availability closures, is something for which
compensating functionality can be adequately supplied.


Absolutely. Hmm, it could even be fun to make :)
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jan 22 '06 #8

P: n/a
In article <r7**********@hotpop.com>, Lasse Reichstein Nielsen
<lr*@hotpop.com> writes

<snip>
I'm
just missing a direct approach to prototype based programming, e.g.,
the clone method that other prototype based languages have.

<snip>

As well as
javascript != Java
we now have to say
javascript != Self
In other words, javascript really is different.

John
--
John Harris
Jan 22 '06 #9

P: n/a
In article <11**********************@o13g2000cwo.googlegroups .com>,
ro********@gmail.com writes

<snip>
[1] Terminology is important. It appears that 'constructor' as a term
in Javascript has been borrowed from other OO languages without
ensuring that the term really continues to appropriately apply (if it
ever did).
It's like a building site. 'new' buys the land and does the initial
bulldozing work. The constructor constructs the building on the prepared
land. The end result is an office block like all the other office blocks
in the area.

Alternatively, 'new' does the work that's the same for all objects,
whatever kind they might be. The constructor does the work that's
different for different kinds. You're even allowed to have parameters
that give you a red convertible here and a green convertible there.

Changing 'new' to 'create' and "constructor" to "initialiser" isn't
going to make any difference and would have just as many critics.

The real 'constructor' is the 'new' operation process which
delivers a new object and hooks it into the prototype chain.

<snip>

But according to ECMA 262 all that 'new' does is check that it's being
applied to a constructor. It's the constructor that does all the work of
creating an object and hooking up the prototype chain.

John
--
John Harris
Jan 22 '06 #10

P: n/a
John G Harris wrote:
In article <11**********************@o13g2000cwo.googlegroups .com>,
ro********@gmail.com writes

<snip> [...]
Changing 'new' to 'create' and "constructor" to "initialiser" isn't
going to make any difference and would have just as many critics.


Actually, if you read that as an advocacy for change, that would not
be correct. I'm simply pointing out that I think that perhaps better
terminology could have been chosen, which in turn might help the
non-initiated to more quickly understand. Even though I provided an
alternative as an example, I haven't even really begun to think about
what might be the best alternative.
The real 'constructor' is the 'new' operation process which
delivers a new object and hooks it into the prototype chain.

<snip>

But according to ECMA 262 all that 'new' does is check that it's being
applied to a constructor. It's the constructor that does all the work of
creating an object and hooking up the prototype chain.


Your reading of ECMA-262, I believe, is incorrect. As Lasse describes
above, the 'new' operator causes an invocation of the internal
[Construct] method of the function object (note 11.22.2 Step 5 (and the
second Step 6)), as it must do - otherwise you wouldn't get a new
object. That is what I referred to as the "'new' operation process",
because it all occurs under the surface and isn't evident.

The only thing that most people see when they look at the external
declaration of a function, whether they've coded it or not, is the
Javascript code itself. The fact that there is some wonderful magic
that occurs underneath when a 'new' operator is applied during
execution may not be particularly important to them. The fact that the
underlying function object has a [Construct] method is by and large
irrelevant (except to those who hold great interest in internal
specification and operation). There are most certainly other ways for
this to occur, and no-one would be able to tell the difference.

What is of most important, I think, is to have the basic knowledge that
functions are objects, along with the understanding that a new object
comes into existence under the application of the 'new' operator during
execution -- and that object is then tailored (not constructed) by the
code they can actually visually see and read.

../rh

Jan 22 '06 #11

P: n/a
> I don't necessarily think it's such a bad idea to have constructor
methods. It looking like class based programming on the surface
probably did a lot to get Javascript popular in the beginning. I'm
just missing a direct approach to prototype based programming, e.g.,
the clone method that other prototype based languages have.


I agree. I think JavaScript's attempt to dress a prototypal pattern up as a
classical pattern is confusing. So I made my own object function which produces
an object using another object as the prototype:

function object(o) {
function f() {}
f.prototype = o;
return new f();
}

With the object function in my toolkit, I can program in a pure prototypal
style. I find it is very effective.

http://www.crockford.com/javascript/
Jan 23 '06 #12

P: n/a
Douglas Crockford wrote:

[unfortunately with missing attribution to Lasse Reichstein Nielsen]
I don't necessarily think it's such a bad idea to have constructor
methods. It looking like class based programming on the surface
probably did a lot to get Javascript popular in the beginning. I'm
just missing a direct approach to prototype based programming, e.g.,
the clone method that other prototype based languages have.


I agree. I think JavaScript's attempt to dress a prototypal pattern up as a
classical pattern is confusing. So I made my own object function which produces
an object using another object as the prototype:

function object(o) {
function f() {}
f.prototype = o;
return new f();
}

With the object function in my toolkit, I can program in a pure prototypal
style. I find it is very effective.


I really don't wish to be disrespectful (it's just seems to be an
inherent part of my nature that's entirely agains my wishes ;-)), but
exactly what illumination does the re-naming of Lasse's 'clone'
function have to offer, other than to say you find it effective for
progarmming in a 'pure prototypical style'.

What do you, as one of the promoters of Javascript, and one who has
provided more useful insights than anyone I'm aware of as to the
capabilities of Javascript (and lo its weaknesses), think about a
re-think of how one accesses and maniputlates the object model under
which Javascript manifests? What do you think about an object-oriented
approach to object creation?

What do you think about going even further, given prototypal
flexibility in not only considering extents within the hierarchical
object model, but provision for insertion of object prototypes above
existing levels (after all, whats the difference in providing
slot/property manipulation capability versus grouped slot manipulation
at higher levels)?

../rh

Jan 23 '06 #13

P: n/a
ro********@gmail.com writes:
John G Harris wrote:
But according to ECMA 262 all that 'new' does is check that it's being
applied to a constructor. It's the constructor that does all the work of
creating an object and hooking up the prototype chain.

Your reading of ECMA-262, I believe, is incorrect.
It's vague enough that it could also be correct.
As Lasse describes above, the 'new' operator causes an invocation of
the internal [Construct] method of the function object (note 11.22.2
Step 5 (and the second Step 6)), as it must do - otherwise you
wouldn't get a new object.


This is true. For function objects, the [Construct] method will create
a new object and call the function's [Call] method with "this" set
to the new object. For host objects with a [Construct] method, this
method is the constructor, and it does the "new"'ing.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jan 23 '06 #14

P: n/a
Lasse Reichstein Nielsen wrote:
ro********@gmail.com writes:
John G Harris wrote:

But according to ECMA 262 all that 'new' does is check that it's being
applied to a constructor. It's the constructor that does all the work of
creating an object and hooking up the prototype chain.

Your reading of ECMA-262, I believe, is incorrect.


It's vague enough that it could also be correct.


But not if you also look at [Construct] under 8.6.2. There is says
"Constructs an object. Invoked via the new operator...", which makes it
clear that 'new' does more than 'check that it's being applied to a
constructor'. Or am I missing your point?

It also says there that "Objects that implement this internal method -
[Construct] - are called constructors.", which is absolutely correct
and I am perfectly OK with as an internal description. And even an
external description, were it to be that an alternate term is coined
and used to better describe the role (timing of the effect of the
action) related to the user-level executable portion of the function
object.

../rh

Jan 23 '06 #15

P: n/a
VK
Many people wrote in this thread:
About inheritance in JavaScript


....and still no one dared to say "sex" :-)

I guess I have to do it :-)

Inheritance in JavaScript is not fully implemented or other words...
here comes... broken.
Object instance remembers its immediate parent (actual constructor),
but it has no clue about parents of its parent (super constructors).
Same picture for methods and fields withing object itself.

There are different ways to overcome this limitation. One can manually
patch the prototype chain (I see it as the most used up to date).

In my variant one could manually mark methods/fields like

function C1() {
C2.call(this);
this.C1_method = function(s){alert(s);};
}

function C2() {
C3.call(this);
this.C2_method = function(s){alert(s);};
this.C2_method.construct = C2;
}
....

In any case one have *manually* do something and it will stay the same
until normal OOP paradigm is implemented (including super() call).

JScript.Net doesn't have this problem anymore, but JavaScript 1.5 / 1.6
(FF 1.5) still does.

Again - it is not a blocking limitation but please stop call it "a core
language feature" ;-)

Jan 23 '06 #16

P: n/a
ro********@gmail.com writes:
But not if you also look at [Construct] under 8.6.2. There is says
"Constructs an object. Invoked via the new operator...", which makes it
clear that 'new' does more than 'check that it's being applied to a
constructor'. Or am I missing your point?
Maybe :)
The [Construct] method is the one that I consider the *real*
constructor. The "new" operator checks that its argument has a
[Construct] method, and then calls it. That's all the "new" operator
really does. Which is why I agreed with what John G. Harris originally
wrote.

It's just a slightly different use of the word "constructor" than
ECMAScript uses, as you point out ...
It also says there that "Objects that implement this internal method -
[Construct] - are called constructors.",
(which includes all language functions)
which is absolutely correct and I am perfectly OK with as an
internal description. And even an external description, were it to
be that an alternate term is coined and used to better describe the
role (timing of the effect of the action) related to the user-level
executable portion of the function object.


"Initializer" would be my suggestion :)

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jan 23 '06 #17

P: n/a
"VK" <sc**********@yahoo.com> writes:
Inheritance in JavaScript is not fully implemented or other words...
here comes... broken.
As in: does not work like you think it should? :)
Object instance remembers its immediate parent (actual constructor),
Hmm, I can't see the constructor as a parent in any way. It's not in
the prototype chain. All it really is, is an overwriteable property of
the default prototype object on functions.
That prototype object is the parent, not the function holding it.

If you create the much maligned clone method:

function clone(obj) {
function _(){};
_.prototype = obj;
return new _();
}

then the result of
clone(x) // x refers to some object
has no reference whatsoever to the "constructor function" used to
create it.
but it has no clue about parents of its parent (super constructors).
It has the internal reference to its prototype's prototype, but no
standardized way of accessing it. Which is good for encapsulation.
Same picture for methods and fields withing object itself.
Not sure I understand. You want to be able to track fields and methods
back to the constructor function that added them to the prototype
chain?
There are different ways to overcome this limitation. One can manually
patch the prototype chain (I see it as the most used up to date). .... this.C2_method = function(s){alert(s);};
this.C2_method.construct = C2;
That would pretty much preclude reusing functions :)
In any case one have *manually* do something and it will stay the same
until normal OOP paradigm is implemented (including super() call).
If "normal OOP paradigm" is class based, then I wouldn't hold my
breath.
JScript.Net doesn't have this problem anymore, but JavaScript 1.5 / 1.6
(FF 1.5) still does.
JScript.Net has classes, which do what you want to do.
JavaScript 1.5/ECMAScript 3 is not class based, so obviously class-based
thinking will not work. If that is how you think, then surely the
language will be "broken" to you, but I can hardly fault the language
for being what it was designed to be.
Again - it is not a blocking limitation but please stop call it "a core
language feature" ;-)


If anything, being prototype based instead of class based is one of the
core characteristica of Javascript. That and having first class closures.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jan 23 '06 #18

P: n/a
In article <11**********************@z14g2000cwz.googlegroups .com>,
ro********@gmail.com writes
John G Harris wrote:
<snip>
But according to ECMA 262 all that 'new' does is check that it's being
applied to a constructor. It's the constructor that does all the work of
creating an object and hooking up the prototype chain.


Your reading of ECMA-262, I believe, is incorrect.


If you bother to read ECMA 262, v3, sections 11.2.2 and 13.2.2 you'll
see that they're remarkably clear and exactly what I said.
<snip>The only thing that most people see when they look at the external
declaration of a function, whether they've coded it or not, is the
Javascript code itself. The fact that there is some wonderful magic
that occurs underneath when a 'new' operator is applied during
execution may not be particularly important to them. The fact that the
underlying function object has a [Construct] method is by and large
irrelevant (except to those who hold great interest in internal
specification and operation). There are most certainly other ways for
this to occur, and no-one would be able to tell the difference.

What is of most important, I think, is to have the basic knowledge that
functions are objects, along with the understanding that a new object
comes into existence under the application of the 'new' operator during
execution -- and that object is then tailored (not constructed) by the
code they can actually visually see and read.


All sorts of things go on that don't appear in the programmer's source
code : manipulating the call stack, searching the prototype chain,
garbage collection, and so on. Why aren't you complaining about those,
especially garbage collection.

John
--
John Harris
Jan 23 '06 #19

P: n/a
VK

Lasse Reichstein Nielsen wrote:
"VK" <sc**********@yahoo.com> writes:
Inheritance in JavaScript is not fully implemented or other words...
here comes... broken.
As in: does not work like you think it should? :)


function C1() {
C2.call(this);
this.C1_method = function(s){alert(s);};
}

function C2() {
C3.call(this);
this.C2_method = function(s){alert(s);};
}

function C3() {
this.C3_method = function(s){alert(s);};
}

var obj1 = new C1();

// I expect this to be true:
alert (obj1 instanceof C1);
// and it is true as expected

// I expect this to return a reference to C1:
alert(obj1.constructor);
// and it does return the expected reference

// It would be nice to get a reference to C2
// by using:
alert(obj1.constructor.constructor);
// but it returns native Function constructor

That could be due to my ignorance (and it most probably is) but "the
end of chain" comes too quickly. I would prefer to have constructors
inheritance tree but itself and do not bother with it manually.

If you create the much maligned clone method:

function clone(obj) {
function _(){};
_.prototype = obj;
return new _();
}

then the result of
clone(x) // x refers to some object
has no reference whatsoever to the "constructor function" used to
create it.
There are a lot of things one can do with JavaScript ;-)
But what would be the purpose of the above? And how does it facilitate
the inheritance management?
Not sure I understand. You want to be able to track fields and methods
back to the constructor function that added them to the prototype
chain?


Right.
In any case one have *manually* do something and it will stay the same
until normal OOP paradigm is implemented (including super() call).


If "normal OOP paradigm" is class based, then I wouldn't hold my
breath.


OOP paradigm - not COP (Class Oriented Programming) paradigm ;-)

super was a reserved word in JavaScript since the beginning, so it's
not a Microsoft maldoing.

Jan 23 '06 #20

P: n/a
"VK" <sc**********@yahoo.com> writes:
// It would be nice to get a reference to C2
// by using:
alert(obj1.constructor.constructor);
// but it returns native Function constructor

That could be due to my ignorance (and it most probably is) but "the
end of chain" comes too quickly. I would prefer to have constructors
inheritance tree but itself and do not bother with it manually.
"Constructor functions" in Javascript are not part of the inheritance
chain at all. In your example, you have no inheritance at all, except
what is created by the "new C1()" expression.
If you create the much maligned clone method:

.... There are a lot of things one can do with JavaScript ;-)
But what would be the purpose of the above? And how does it facilitate
the inheritance management?


The clone function takes an object as parameter, and then creates a
new object with the given object as its prototype. That means that

var o = {};
var p = clone(o);
o.foo = 42;
alert(p.foo); //alerts 42, because "p" inherits all properties from "o".

Try this usage of "clone" for inheritance:

function LC2() {
this.foo = 42;
}
LC2.prototype.getFoo = function getFoo() { return this.foo; };

function LC1() {
LC2.call(this);
this.bar = 37;
}
LC1.prototype = clone(LC2.prototype);
LC1.prototype.constructor = LC1;
LC1.prototype.getBar = function getBar() { return this.bar; };

var l1 = new LC1();
alert(l1.getFoo());

LC2.prototype.getBaz = function getBaz() { return "voodoo"; }
alert(l1.getBaz());

Here you see actual inheritance between objects. The created object
referred to by "l1" has both LC1.prototype and LC2.prototype in its
prototype inheritance path.

The constructor functions themselves are forgotten as soon as the
objects are created. They merely initalize the object. You can
visualize it as:
LC2 -------- .prototype ------> { getFoo: ... }
^ ^
|(calls) | [Proto]
LC1 -------- .prototype ------> { getBar: ... }
^
| [Proto]
l1
The inheritance happens between the objects only. Functions are merely
mediators for creating the new objects and giving them a prototype
chain. The default chain of a new object, if you don't change the
prototype object of a constructor function, is just the function's
prototype object followed by (the initial value of) Object.prototype.
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jan 23 '06 #21

P: n/a
John G Harris wrote:
In article <11**********************@z14g2000cwz.googlegroups .com>,
ro********@gmail.com writes
John G Harris wrote:
<snip>
But according to ECMA 262 all that 'new' does is check that it's being
applied to a constructor. It's the constructor that does all the work of
creating an object and hooking up the prototype chain.


Your reading of ECMA-262, I believe, is incorrect.


If you bother to read ECMA 262, v3, sections 11.2.2 and 13.2.2 you'll
see that they're remarkably clear and exactly what I said.


Fine, I mis-interpreted what you were saying to some extent. If you
(bother to :-)) read what I said, I wasn't absolute about it, there was
an "I believe" qualification. Whether it's 'exactly' as you said is
highly debatable, but who has the time or interest for that? I now
understand, at least, what you were trying to say ;-).

<snip>
The only thing that most people see when they look at the external
declaration of a function, whether they've coded it or not, is the
[...]
All sorts of things go on that don't appear in the programmer's source
code : manipulating the call stack, searching the prototype chain,
garbage collection, and so on. Why aren't you complaining about those,
especially garbage collection.

That's just because I prefer to do one thing at a time ;-).

No, actually I was trying to approach this from a "can this stuff be
made easier to learn, retain and use" perspective (and, no I'm not
intending to write a book, not even produce a Javascript how-to page).From the point of view of someone newly introduced and trying to

understand the language, does that person need to know "there's a
call-stack that's being manipulated and how it's manipulated?', or that
'the language supports recursion?', assuming that they already know
what recursion is.

Basically it comes down to whether there's a known abstraction, or
prior knowledge that can be applied, that assists in grasping the
utility and capabilty of the language. In some cases there's no
avoiding learning new terminology, or taking old terminology and
learning how it has been applied to new things.

However, in thinking things through a bit further, if you take the
triple:

(new, prototype object, function object)

does that not then abstractly represent an object replication factory?
And isn't object replication of the most fundamental operations OO
programming, Javascript in particular?

So, since it appears that I may be the only one who has a bit of a
problem with the term "constructor", is to move my approach to it up a
level, and not have to be concened about function objects and their
"constructor" nature and nomenclature at all. I'll generally be
thinking in terms of the triple and the replication that results when
employed, which should have considerably more utility in terms of
thought processes.

Consider the "constructor" terminology matter dropped (it was really
just an aside to the original post, anyway).

../rh

Jan 24 '06 #22

P: n/a
VK

ro********@gmail.com wrote:
No, actually I was trying to approach this from a "can this stuff be
made easier to learn, retain and use" perspective (and, no I'm not
intending to write a book, not even produce a Javascript how-to page).
From the point of view of someone newly introduced and trying to

understand the language, does that person need to know "there's a
call-stack that's being manipulated and how it's manipulated?', or that
'the language supports recursion?', assuming that they already know
what recursion is.

Basically it comes down to whether there's a known abstraction, or
prior knowledge that can be applied, that assists in grasping the
utility and capabilty of the language. In some cases there's no
avoiding learning new terminology, or taking old terminology and
learning how it has been applied to new things.


You can take me as a laboratory rat :-)
I've been learning inheritance in JavaScript by Cars and Employee
samples (these "Hello, world" of inheritance) from Netscape docs. I
never had any problem with the idea that
var myCar = new Car();
returns *new instance of Car object*
that (myCar instanceof Car)
or that (myCar.constructor == Car).

That may be wrong, but it was perfectly logic for my mind and I assure
you that it is perfectly logic for any beginner. But even now when I am
*kind of* experienced, it still has perfect sense for me.

The only thing I'm missing is the tools to study the whole chain
*within this logic* - I need my super(). That was well on its way till
Summer 2003 when JavaScript 2.0 project suddently died. :-(

Jan 24 '06 #23

P: n/a
VK wrote:
ro********@gmail.com wrote: [...]
You can take me as a laboratory rat :-)


Already so, but thank-you for the generous, if nonetheless belated,
permission. :-)

(I'd say that one of the reasons you seem to have encountered
difficulty in this group is that you continually try to tell everyone
how to find the cheese, when you haven't once yet found your way
through the maze).

[...]

../rh

Jan 24 '06 #24

P: n/a
VK

ro********@gmail.com wrote:
(I'd say that one of the reasons you seem to have encountered
difficulty in this group is that you continually try to tell everyone
how to find the cheese, when you haven't once yet found your way
through the maze).


So shall be it. Sorry for participating in a discussion for above
average IQ level. Enjoy.

Jan 24 '06 #25

P: n/a
In article <11**********************@f14g2000cwb.googlegroups .com>,
ro********@gmail.com writes

<snip>
However, in thinking things through a bit further, if you take the
triple:

(new, prototype object, function object)

does that not then abstractly represent an object replication factory?
And isn't object replication of the most fundamental operations OO
programming, Javascript in particular?

<snip>

Replication is an unfortunate word to use here. It implies an exact
copy, a clone. It's possible for the programmer to make the function
produce an exact copy of another object, but it's not easy and it's not
common.

Also it would be clearer to say prototype chain instead of prototype
object.

It looks like your efforts to explain javascript in terms of another
language are threatening to lead you astray.

John
--
John Harris
Jan 24 '06 #26

P: n/a
John G Harris wrote:
In article <11**********************@f14g2000cwb.googlegroups .com>,
ro********@gmail.com writes [...]
Replication is an unfortunate word to use here. It implies an exact
copy, a clone. It's possible for the programmer to make the function
produce an exact copy of another object, but it's not easy and it's not
common.

Not really, because I wasn't referring to cloning operations (deep or
otherwise) in the sense that you are. I was referring to the
fundamental object creation process that has 3 essential ingredients
(new, prototype object, and function object) at the programming level.

When you carry out the process of setting a prototype on a function
object and apply the new operator you create a new object. If you
repeat that process, multiple times, using the same function object,
you get a number of replica(te)s (or duplicates, or clones). And that
is a very common thing to do, except that generally arguments would be
supplied on the function invocation that provide at a minimum identity
or some other form of object differentiation in the process.

I chose to use 'replicate/replication' because clone (or duplicate)
generally implies an exact copy, objects which are indistinguishable
through test or presentation of characteristics alone. The word
'replica(te)' is in general less stringent as it can imply a close
copy.
Also it would be clearer to say prototype chain instead of prototype
object.
I would think not, John.

It looks like your efforts to explain javascript in terms of another
language are threatening to lead you astray.


That would be a mis-interpretation of approach. As motion is relative,
perhaps so is perception. ;-)

../rh

Jan 25 '06 #27

P: n/a
VK wrote:
ro********@gmail.com wrote:
(I'd say that one of the reasons you seem to have encountered
difficulty in this group is that you continually try to tell everyone
how to find the cheese, when you haven't once yet found your way
through the maze).


So shall be it. Sorry for participating in a discussion for above
average IQ level. Enjoy.


I can see my earlier response was a bit biting, and the humor (well OK,
I thought there was some humor) failed to salve the wound. However, the
parenthetical was actually intended to be helpful (toward seeing why
you evoke the responses you do), even if it did carry the theme --
perhaps too far.

../rh

Jan 25 '06 #28

P: n/a
In article <11**********************@g14g2000cwa.googlegroups .com>,
ro********@gmail.com writes

<snip>
When you carry out the process of setting a prototype on a function
object and apply the new operator you create a new object. If you
repeat that process, multiple times, using the same function object,
you get a number of replica(te)s (or duplicates, or clones). And that
is a very common thing to do, except that generally arguments would be
supplied on the function invocation that provide at a minimum identity
or some other form of object differentiation in the process.

<snip>

Even so, replicate still isn't appropriate for the first new as there
isn't anything to be a replica of. And in some cases objects can differ
even when there are no parameters. Think of new Date().

Also it would be clearer to say prototype chain instead of prototype
object.


I would think not, John.

<snip>

If the 'prototype' property is null then there is no object, but there
is still a chain, empty as it happens.

John
--
John Harris
Jan 25 '06 #29

P: n/a
John G Harris wrote:
In article <11**********************@g14g2000cwa.googlegroups .com>,
ro********@gmail.com writes

<snip>
When you carry out the process of setting a prototype on a function
object and apply the new operator you create a new object. If you
repeat that process, multiple times, using the same function object,
you get a number of replica(te)s (or duplicates, or clones). And that
is a very common thing to do, except that generally arguments would be
supplied on the function invocation that provide at a minimum identity
or some other form of object differentiation in the process. <snip>

Even so, replicate still isn't appropriate for the first new as there
isn't anything to be a replica of.


I think that could be why I said "create a new object" first :-).
And in some cases objects can differ
even when there are no parameters. Think of new Date().

Fair enough. The function initialization could also generate random
pertubations of the object in the absence of parameters as well. That
possibility may be important to note as a detail, but it's not
particularly germane to the substance of what was put forth.

[...]
If the 'prototype' property is null then there is no object, but there
is still a chain, empty as it happens.


Hmm. The prototype property is never null (only perhaps as null object,
which is still an object) except as stopper at the programmer
inaccessible top of the internal chain. The prototype property that is
assigned may not necessarily be an object, but if not, a default object
will be substituted during the creation process.

I see no reason at all to make reference the "prototype chain", an
internal designation, when it's an object that is used at the
programming level in order to manifest a new object.

Does it have an effect on the prototype chain? Yes it does, but that's
another separate matter entirely.

../rh

Jan 26 '06 #30

P: n/a
In article <11*********************@z14g2000cwz.googlegroups. com>,
ro********@gmail.com writes
John G Harris wrote:
<snip>
Even so, replicate still isn't appropriate for the first new as there
isn't anything to be a replica of.


I think that could be why I said "create a new object" first :-).


Why not use the word "create" everywhere. It's simple and honest.
<snip>
If the 'prototype' property is null then there is no object, but there
is still a chain, empty as it happens.


Hmm. The prototype property is never null


If you do

function Thing() { ... }
Thing.prototype = null;
var t = new Thing();

then t is given the Object prototype object, call it Opo, as its
prototype. Your new object has an internal prototype property that can
never be null. However, the Opo's internal prototype property *is* null.

So, there is an object with a null internal prototype property, but it's
an object created by internal magic not by the kind of constructor we
can write.

(only perhaps as null object,
which is still an object)
No. In javascript Null and Object are different types. In C, C++, and
Java, null is a pointer or reference with a special value. In javascript
null is the only value belonging to the Null type. It's not a reference,
nor is it a warped object.

except as stopper
Since every prototype chain ends at a null, by definition, I wouldn't
call it exceptional.
<snip>I see no reason at all to make reference the "prototype chain", an
internal designation, when it's an object that is used at the
programming level in order to manifest a new object.

Does it have an effect on the prototype chain? Yes it does, but that's
another separate matter entirely.


Let's agree to differ here. Your view looks along the prototype chain so
that the first prototype object hides all the others.

My view looks from the side so that all the prototype objects can be
seen. This has the advantage that I can see which functions are hidden
by objects closer to the front of the chain. More likely, it shows which
haven't been hidden but should have been.

John
--
John Harris
Jan 27 '06 #31

P: n/a
John G Harris wrote:
In article <11*********************@z14g2000cwz.googlegroups. com>,
ro********@gmail.com writes
John G Harris wrote:
<snip>
Even so, replicate still isn't appropriate for the first new as there
isn't anything to be a replica of.


I think that could be why I said "create a new object" first :-).


Why not use the word "create" everywhere. It's simple and honest.


By implication, I gather there's something you find complex and
dishonest about 'replicate'. These are objects, not counterfeit (money,
paintings, etc.) being passed off as the real thing to unsuspecting
victims. They are completely legitimate, as is the process, as is the
term 'replicate'.

Replication is a creation process, but it's a process that doesn't
simply create, it produces copies. And that's the answer to your "Why?"
-- some words add meaning, and therefore are highly preferable to terms
that are more general in nature.

Is this really rocket science to you, as you seem to be making it out
to be, or do you just greatly enjoy the keep of a pot well stirred? ;-)

<snip>
If the 'prototype' property is null then there is no object, but there
is still a chain, empty as it happens.
Hmm. The prototype property is never null


If you do

function Thing() { ... }
Thing.prototype = null;
var t = new Thing();

then t is given the Object prototype object, call it Opo, as its
prototype. Your new object has an internal prototype property that can
never be null. However, the Opo's internal prototype property *is* null.

So, there is an object with a null internal prototype property, but it's
an object created by internal magic not by the kind of constructor we
can write.

(only perhaps as null object,
which is still an object)


No. In javascript Null and Object are different types. In C, C++, and
Java, null is a pointer or reference with a special value. In javascript
null is the only value belonging to the Null type. It's not a reference,
nor is it a warped object.


In this you're correct. I had forgotten that 'null' is a primitive, in
spite of the fact that 'typeof null' returns 'object'. However, the
fact that 'null' is not an object is the reason that 'Opo', as you've
chosen to call it, is substituted.

except as stopper
Since every prototype chain ends at a null, by definition, I wouldn't
call it exceptional.


Then why did you bother to raise it as an issue in the first place?
(No, I really don't want an answer, the questions herein are all
rhetorical.)

<snip>
I see no reason at all to make reference the "prototype chain", an
internal designation, when it's an object that is used at the
programming level in order to manifest a new object.

Does it have an effect on the prototype chain? Yes it does, but that's
another separate matter entirely.
Let's agree to differ here. Your view looks along the prototype chain so
that the first prototype object hides all the others.


Gaaaccck! Here we were just about to agree to differ :-), and you
follow up with presentation of yet another completely unfathomable
misconception. Great bait, but I'm not biting.
My view looks from the side so that all the prototype objects can be
seen. This has the advantage that I can see which functions are hidden
by objects closer to the front of the chain. More likely, it shows which
haven't been hidden but should have been.


I think it would be most appropriate for me to say at this time, as at
the very least one of us is moving on (namely me ;-)), that I'm moving
on.

../rh

Jan 28 '06 #32

This discussion thread is closed

Replies have been disabled for this discussion.