469,326 Members | 1,216 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,326 developers. It's quick & easy.

prototypical inheritance

Can anyone help here?

I have two classes, Rect and RoundRect.

RoundRect is a subclass of Rect

mstr.chart.Rect = (function(){

function Rect(x, y, w, h) { /* this is the class constructor */
this.x = x;
this.y = y;
this.w = w;
this.h = h;
};

Rect.prototype.toString = function() {
var str = 'x, y: (' + this.x + ',' + this.y + ') w, h : (' +
this.w + ', ' + this.h + ')';
return str;
}

return Rect; })();

mstr.chart.RoundRect = (function() {
function RoundRect(x,y,w,h,arc) {
mstr.chart.Rect.apply(this, arguments);
this.arc = arc;
}

RoundRect.prototype.toString = function() {
return 'testing directly';
}

RoundRect.prototype = new mstr.chart.Rect();

return RoundRect;
})();

-----------------------------------------------------------------------------
When I alert on toString method of RoundRect, it shows me Rect's
toString. What am I doing wrong here?

var myRect = new mstr.chart.RoundRect (0, 0, 2, 2, 0.2);
alert(tooltipRect.toString());

Thanks,
Srini

Aug 17 '07 #1
2 1246
sr*******************@gmail.com wrote:
I have two classes, Rect and RoundRect.
You don't.
RoundRect is a subclass of Rect
It isn't.

http://javascript.crockford.com/javascript.html
mstr.chart.Rect = (function(){

function Rect(x, y, w, h) { /* this is the class constructor */
It isn't. It is the declaration of a method local to the function you are
creating with this lambda FunctionExpression. Properties of the local
Variable Object are usually not available outside their scope (although some
implementations allow that); however, you return a reference to this method,
thereby creating a closure.

Therefore,you can use the returned Function object as constructor of a
prototype object.
this.x = x;
this.y = y;
this.w = w;
this.h = h;
};

Rect.prototype.toString = function() {
var str = 'x, y: (' + this.x + ',' + this.y + ') w, h : (' +
this.w + ', ' + this.h + ')';
return str;
}

return Rect; })();

mstr.chart.RoundRect = (function() {
function RoundRect(x,y,w,h,arc) {
mstr.chart.Rect.apply(this, arguments);
this.arc = arc;
}

RoundRect.prototype.toString = function() {
return 'testing directly';
}

RoundRect.prototype = new mstr.chart.Rect();
First, there is no point in this assignment as it overwrites everything that
was assigned defined before to this object's property. But see below.
return RoundRect;
})();

-----------------------------------------------------------------------------
When I alert on toString method of RoundRect, it shows me Rect's
toString.
[...]
var myRect = new mstr.chart.RoundRect (0, 0, 2, 2, 0.2);
alert(tooltipRect.toString());
(I assume for brevity that `tooltipRect' is a copy-paste error for `myRect',
and that an object reference is the referred object. Also, I omit
`mstr.chart.' as it does not matter here.)

As it should. You assign a new Rect object (below: r) to
RoundRect.prototype. So the prototype chain of RoundRect objects (such as
`myRect' here) looks like

myRect ---r ---Rect.prototype ---Object.prototype ---...

when it should look like

myRect ---RoundRect.prototype ---Rect.prototype ---...

Therefore, myRect.toString refers to Rect.prototype.toString, as `r'
inherits that through *its* prototype chain.
What am I doing wrong here?
IMHO, you do things unnecessarily complicated and thus lose overview.
The above could be rewritten as follows:

function Rect(x, y, w, h)
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}

Rect.prototype.toString = function()
{
// or one might employ an sprintf(1) equivalent
var str = new Array(
"x, y: (", this.x, ",", this.y, ") w, h : (",
this.w, ", ", this.h, ")"
).join("");

return str;
};

function RoundRect(x, y, w, h, arc)
{
Rect.apply(this, arguments);
this.arc = arc;
}

// Courtesy of Lasse Reichstein Nielsen
// Message-ID: <ve**********@hotpop.com>
function clone(obj)
{
function Dummy() {}
Dummy.prototype = obj;
return new Dummy();
}

RoundRect.prototype = clone(Rect.prototype);
RoundRect.prototype.toString = function()
{
return 'testing directly';
};

var myRect = new RoundRect(0, 0, 2, 2, 0.2);
window.alert(myRect); /* .toString() is implicit with window.alert() */

However, if you need to retain your object model, you have to switch the
assignments to RoundRect.prototype.toString and RoundRect.prototype. Then
you would still have

myRect ---r ---Rect.prototype

as prototype chain, but since r.toString() existed, it would be called
instead of Rect.prototype.toString().

The next step would be to set up a real prototype chain:

RoundRect.prototype = Rect.prototype

However, that would result in

myRect ---RoundRect.prototype === Rect.prototype ---...

and every modification of the RoundRect.prototype object would affect
Rect.prototype as well.

Therefore, the clone() solution I used above, which would result in

myRect ---RoundRect.prototype ---Rect.prototype ---...

as it was probably intended.
HTH

PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
Aug 17 '07 #2
>
mstr.chart.RoundRect = (function() {
function RoundRect(x,y,w,h,arc) {
mstr.chart.Rect.apply(this, arguments);
this.arc = arc;
}

RoundRect.prototype.toString = function() {
return 'testing directly';
}
// now override the prototype, obliviating the toString method. Oh no!
RoundRect.prototype = new mstr.chart.Rect();

return RoundRect;

})();
Switch them around and it should work:
RoundRect.prototype = new mstr.chart.Rect();
RoundRect.prototype.toString = function() {
return 'testing directly';
}

There are some nice subleties to this approach of extend:
http://developer.yahoo.com/yui/docs/Lang.js.html

The first is that a no-arg constructor is invoked to trigger prototype
inheritance -- not the real constructor, saving you the headache of
unwanted side effects.

Second, they patched around stupid 'ol JScript DontEnum bug.

I mentioned this a few times on YUI team mail (Yahoo internal) and
filed a bug on Y! bugzilla (also internal) and they did it! They
patched for the stupid IE DontEnum bug. Woulda been nice if they'd
made some mention of my name somewhere. It was a pretty clear and
descript bug rep't, too (at least I thought so). I'm my only advocate :
(

I'm not pimping this library, but it is, in my opinion, the best
approach for prototype inheritance). (And I'm a little proud to have
contributed in some slight way to improve the best inheritance
approach).

Garrett
>
-----------------------------------------------------------------------------
When I alert on toString method of RoundRect, it shows me Rect's
toString. What am I doing wrong here?

var myRect = new mstr.chart.RoundRect (0, 0, 2, 2, 0.2);
alert(tooltipRect.toString());

Thanks,
Srini

Aug 18 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by Ricky Romaya | last post: by
reply views Thread by John Hunter | last post: by
2 posts views Thread by Graham Banks | last post: by
4 posts views Thread by JKop | last post: by
5 posts views Thread by Morgan Cheng | last post: by
22 posts views Thread by Matthew Louden | last post: by
6 posts views Thread by Bart Simpson | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
reply views Thread by harlem98 | last post: by
reply views Thread by listenups61195 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.