473,406 Members | 2,451 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

constructor for a derived object is same as that of its parent

I am trying to learn the concept of constructors in ECMAScript. I
executed following code (See execution in Rhino JavaScript shell):
function Foo(a)
{
this.a = a;
}

function Bar(b)
{
this.b = b;
}
Bar.prototype = new Foo(1);
var x = new Foo(2);
var y = new Bar(3);

Now I expect y.constructor to give me Bar, but I am getting Foo.
Can anybody explain?

Following the execution sequence in Rhino JavaScript shell:

Rhino 1.6 release 5 2006 11 18
jsfunction Foo(a)
{
this.a = a;
}
jsfunction Bar(b)
{
this.b = b;
}
jsBar.prototype = new Foo(1);
[object Object]
jsvar x = new Foo(2);
jsvar y = new Bar(3);
jsx.constructor

function Foo(a) {
this.a = a;
}

jsy.constructor

function Foo(a) {
this.a = a;
}

Regards,
Satyajit

Nov 29 '06 #1
12 1743
VK

satyajit wrote:
function Foo(a)
{
this.a = a;
}

function Bar(b)
{
this.b = b;
}
Bar.prototype = new Foo(1);
var x = new Foo(2);
var y = new Bar(3);

Now I expect y.constructor to give me Bar, but I am getting Foo.
Yep... And at the same
alert(y instanceof Bar); // true
or (the same but more "conceptual"):
alert(Bar.prototype.isPrototypeOf(y)); // true

Tricky, is not it? ;-)

I highly suggest you to read and study all samples from:

Eric Lippert
"The JScript Type System, Part Two: Prototypes and constructors"
<http://blogs.msdn.com/ericlippert/archive/2003/11/06/53352.aspx>

This rather short blog post is the *only one* source about JavaScript
inheritance currently existing in the Internet. There can be more of
course, but my two years search did not reveal them. Anything else I
could find is either an erroneus crap or multi-paged revelations
leaving you even more confusing then ever before.

P.S. Eric Lippert is the original maker of Microsoft JScript engine.
That doesn't mean that you have to take each his word as the final
truth: there is a difference between a piano maker and a piano player
:-) I just thought that it should be mentioned that he is not some
"side ECMAScript specialist".

Nov 29 '06 #2
satyajit wrote:
I am trying to learn the concept of constructors in ECMAScript. I
executed following code (See execution in Rhino JavaScript shell):
function Foo(a)
{
this.a = a;
}

function Bar(b)
{
this.b = b;
}
Bar.prototype = new Foo(1);
var x = new Foo(2);
var y = new Bar(3);

Now I expect y.constructor to give me Bar, but I am getting Foo.
Can anybody explain?
This has confused a lot of people but it only shows that the constructor
property is not very intuitive respectively not set in a way that
follows the intuition people have that think in class based terms and
expect "instances" in JavaScript to have a property named constructor
that points to the function constructor.

You might want to check
y.hasOwnProperty('constructor')
and you will find that y does not have an own property of that name.
That means when y.constructor is looked up that the prototype chain is
used to look for the property and so the lookup first looks at
Bar.prototype having a constructor property but it does not have one meaning
Bar.prototype.hasOwnProperty('constructor')
is false too, then follows the lookup of Foo.prototype and
Foo.prototype.hasOwnProperty('constructor')
is true and that constructor property has been set when the Foo function
was created according to section 13.2 of the ECMAScript edition 3
specification.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 29 '06 #3
satyajit wrote:
I am trying to learn the concept of constructors in ECMAScript. I
executed following code (See execution in Rhino JavaScript shell):
function Foo(a)
{
this.a = a;
}

function Bar(b)
{
this.b = b;
}
Bar.prototype = new Foo(1);
var x = new Foo(2);
var y = new Bar(3);

Now I expect y.constructor to give me Bar, but I am getting Foo.
Can anybody explain?
<snip>

When a function object is created it is given a - prototype - property
and that property is assigned a value that is a reference to an object.
That object is then given a - constructor - property that is assigned a
reference to the function object.

If the function object is used to construct an object the value
currently assigned to its - prototype - property is assigned to the new
object's internal [[Prototype]] property, which is then used as the
first object in the new object's prototype chain. Thus this new object
inherits a reference to the function object used as its constructor
through its prototype chain.

You have replaced the object originally assigned to - Bar.prototype -
with an instance of Foo. Thus the object that had the - constructor -
property that referred to Bar has been replaced with an object that is
inheriting a constructor - property through its prototype chain from -
Foo.prototype -. And when that object is assigned to the internal
[[Prootype]] properties of objects created with - new Bar - they
inherit its - constructor - property.

You can mitigate that issue by doing:-

Bar.prototype = new Foo(1)
Bar.prototype.constructor = Foo;

- and then new instances of Bar will inherit a - constructor - property
that refers to - Foo -.

However, you really should not be writing javascript code in which you
need to test for the constructor of any objects (outside of
experimental and testing code). There are no casting issues in
javascript as all objects are really of a single 'class' and in a
loosely typed language like javascript it is a necessary discipline for
the programmer to be keeping track of the types being used and so
situations where you need to query a type at runtime are exceptional.

Richard.

Nov 29 '06 #4
Richard Cornford wrote:
You can mitigate that issue by doing:-

Bar.prototype = new Foo(1)
Bar.prototype.constructor = Foo;

- and then new instances of Bar will inherit a - constructor - property
that refers to - Foo -.
How does that mitigate things? The original poster complained about Foo
being returned by y.constructor and wanted Bar instead. That code above
does not change that, unless you wanted to set
Bar.prototype.constructor = Bar;

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 29 '06 #5
Martin Honnen wrote:
Richard Cornford wrote:
You can mitigate that issue by doing:-

Bar.prototype = new Foo(1)
Bar.prototype.constructor = Foo;

- and then new instances of Bar will inherit a - constructor - property
that refers to - Foo -.

How does that mitigate things? The original poster complained about Foo
being returned by y.constructor and wanted Bar instead. That code above
does not change that, unless you wanted to set
Bar.prototype.constructor = Bar;
You are right. I intended to type Bar and typed Foo instead.

Richard.

Nov 29 '06 #6

satyajit wrote:
I am trying to learn the concept of constructors in ECMAScript.
You may enjoy this tutorial

http://kevlindev.com/tutorials/javas...ance/index.htm

And at least the first of these three videos

http://yuiblog.com/blog/2006/11/27/v...ockford-advjs/

Peter

Nov 29 '06 #7
VK
Peter Michaux wrote:
You may enjoy this tutorial

http://kevlindev.com/tutorials/javas...ance/index.htm

And at least the first of these three videos

http://yuiblog.com/blog/2006/11/27/v...ockford-advjs/
Video is good (though the downstream from the Yahoo server seems poor
as it chocks even on my DSL).

The inheritance article (the first one) is a rather dangerous reading.
It is one of countless "C++ over JavaScript" tutorials: a little
preface about prototype inheritance (just few words do not make a
C++'er too much bored) and then quickly move onto the main part: how to
build inheritance in the "conventional proper" way and do not be
bothered with that stupid prototypes anymore. Such articles constitute
90% of "inheritance in JavaScript" sources, but this one admittedly is
of much better quality than many of what I've seen.

I mean hell - I use "classy" emulation in JavaScript left and right
myself because it's often more easy and quickly in a mixed environment.
But if anyone is targeted to understand how is it *really* ticking
(even if never come to it again and just stick to say prototype.js)
then such articles should be read only after the one I posted.

Nov 29 '06 #8
In article <11**********************@14g2000cws.googlegroups. com>,
Richard Cornford <Ri*****@litotes.demon.co.ukwrites

<snip>
>However, you really should not be writing javascript code in which you
need to test for the constructor of any objects (outside of
experimental and testing code). There are no casting issues in
javascript as all objects are really of a single 'class' and in a
loosely typed language like javascript it is a necessary discipline for
the programmer to be keeping track of the types being used and so
situations where you need to query a type at runtime are exceptional.
To add to that, the 'constructor' property is like 'with' and two-digit
year numbers : each seemed a good idea at the time, but in practice each
causes a lot of confusion and can be done better a different way.

John
--
John Harris
Nov 29 '06 #9

Martin Honnen wrote:
Richard Cornford wrote:
You can mitigate that issue by doing:-

Bar.prototype = new Foo(1)
Bar.prototype.constructor = Foo;

- and then new instances of Bar will inherit a - constructor - property
that refers to - Foo -.

How does that mitigate things? The original poster complained about Foo
being returned by y.constructor and wanted Bar instead. That code above
does not change that, unless you wanted to set
Bar.prototype.constructor = Bar;
Thanks VK, Martin, and Richard for very explanations. Got the reason
after I read Eric Lippert blog.

I did not want to set "Bar.prototype.constructor = Bar;" but was trying
to find out how the constructor and prototypes work. The version of
ECMAScript standard that I got originally from ECMA's site was ECMA-262
standard and that did not have reference to instanceof and
isPrototypeOf(). Getting these concepts from the standard was very
difficult.

However one thing I noticed in the ECMA standard that the String
behaves differently when called as constructor and as function. I
wanted to explore how to do that for my own functions that can be used
as constructor or as conversion type. I tried to make sense of some
earlier posts but could not do so.

- Satyajit

Nov 30 '06 #10
VK
satyajit wrote:
The version of
ECMAScript standard that I got originally from ECMA's site was ECMA-262
standard and that did not have reference to instanceof and
isPrototypeOf(). Getting these concepts from the standard was very
difficult.
The current standard is ECMA-262 3rd edition, so you must be reading
ECMA-262 2nd edition (same standard but the obsolete edition). The 3rd
(current) edition as available at
<http://www.ecma-international.org/publications/standards/Ecma-262.htm>

Please note though that - despite of what the name implies - this
standard describes an ECMAScript-compliant *script engine* so primary
targeted to UA producers and not to the end developers. This way
learning the JavaScript programming by ECMA-262 specs is like learning
to drive by car's technical specs: theoretically possible, practically
very difficult :-)
>From the online resources linked at
<http://www.jibbering.com/faq/#FAQ3_2I would suggest first MSDN
JScript 5.6 documentation as the most consistent (though still not
bug-free):
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/29f83a2c-48c5-49e2-9ae0-7371d2cda2ff.asp>

It is available for download (.chm help file, 2.8Mb) at
<http://www.microsoft.com/downloads/details.aspx?familyid=01592C48-207D-4BE1-8A76-1C4099D7BBB9>
A "Genuine Windows validation" is required, also chm help files need IE
installed to be viewed - so alas this download is useless for many
developers.

(JScript 5.6 is the one running on IE 6 and - with one minor
modification - on IE 7. It corresponds to Mozilla JavaScript 1.5 minus
all Mozilla/Microsoft extensions).

However one thing I noticed in the ECMA standard that the String
behaves differently when called as constructor and as function.
I'm not sure if I fully understand this statement. There can be string
primitive value and string object in javascript: the first one created
implicitly out of string literal, the second one created explicetly by
using String constructor: new String(value) The explicit String
constructor is very rarely used in JavaScript.
I wanted to explore how to do that for my own functions that can be used
as constructor or as conversion type. I tried to make sense of some
earlier posts but could not do so.
In JavaScript the call context defines everything: so the very same
function can act as an object constructor or as a regular subroutine,
depending on how did you call it. Some formal description of your
actual task would be helpful.

Dec 1 '06 #11
VK wrote:
<snip>
In JavaScript the call context defines everything: so the very same
function can act as an object constructor or as a regular subroutine,
depending on how did you call it. Some formal description of your
actual task would be helpful.
Thanks for the resources. To give an example (not a real example) of
what I was trying to find out is as follows:

function MimeType(string extension)
{
if ( /* its a constructor - this is what I want to know how to
check. */ )
{
// initialize MimeType. For jpeg, description is 'image/jpeg'
// Assume that getDescriptionFromExtension() returns a string
// with appropriate description
this.description = getDescriptionFromExtension(extension);
// other initializers..
}
else return getDescriptionFromExtension(extension);
}

I could use it like
var img1 = new MimeType(".jpeg");
img1.description would then be "image/jpeg"

another probable usage:

if ("image/jpeg" == MimeType(extension));

Any quick ideas?

Thanks.
-Satyajit

Dec 5 '06 #12
VK
satyajit wrote:
To give an example (not a real example) of
what I was trying to find out is as follows:

function MimeType(string extension)
{
if ( /* its a constructor - this is what I want to know how to
check. */ )
{
// initialize MimeType. For jpeg, description is 'image/jpeg'
// Assume that getDescriptionFromExtension() returns a string
// with appropriate description
this.description = getDescriptionFromExtension(extension);
// other initializers..
}
else return getDescriptionFromExtension(extension);
}

I could use it like
var img1 = new MimeType(".jpeg");
img1.description would then be "image/jpeg"

another probable usage:

if ("image/jpeg" == MimeType(extension));

Any quick ideas?
The first one is that I'm not excited by this approach ;-) IMO using
the same entity as object constructor and as subroutine depending on
circumstances is a bad practice: even if the used language technically
allows it. It obfuscates the source and it promises many problems with
inheritance (if anyone ever extends your library). You may flush my
opinion out though.

If function is called as constructor, [this] points to the newly
created object instance. (That's if no one is trying to cheat on your
program by substituting context: say by using MimeType.call(null,
args);
Otherwise [this] will point to the Global context which is equal to the
current window object in comparison operations (that's again for a
plain-vanilla situations without any special cases).
So if you insist on the current approach, you may check this == self :

function MimeType(ext) {
if (this == self) {
// presumably called as simple function
return 'foobar';
}
else {
// presumably called as constructor
this.description = 'foobar';
}
}

var foo = new MimeType();
var bar = MimeType();

alert(foo.description); // 'foobar'
alert(bar); // 'foobar'
P.S. I would still disassemble constructor from subroutine. Just try -
you may like it :-)

Dec 5 '06 #13

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

Similar topics

6
by: cppaddict | last post by:
Hi, I know that C++ does not have an explicit super() constructor for calling a Base class constructor from a Derived class's constructor, but my understanding is that C++ implements this...
3
by: pantalaimon | last post by:
I'm trying to write a GUI for a game I'm making. Till now I've always done this: ChildClass(int x,int y) : ParentClass(x,y) whenever my compiler complains about "no default constructor found". But...
45
by: Ben Blank | last post by:
I'm writing a family of classes which all inherit most of their methods and code (including constructors) from a single base class. When attempting to instance one of the derived classes using...
6
by: JC Voon | last post by:
Hi: The parent class have 3 version of constructor: public class Parent public sub New() end sub public sub New(i as integer) myclass.New()
15
by: Manuel | last post by:
The parent is an abstract class, with default implicit constructor: ----------------------------------- class mhwidget { public: virtual void draw()= 0; virtual void setPosition(GLint,...
4
by: craig | last post by:
During construction of an object "parent", if you create a subobject that stores a pointer to the parent (through the "this" pointer), will that pointer be valid when the subobject is later called?...
4
by: Andrew Backer | last post by:
Hello, I am having a problem creating a class dynamically. The class I have is a base class of another, and the parent class has the constructor (which takes one argument). The base class...
13
by: JD | last post by:
Hi, My associate has written a copy constructor for a class. Now I need to add an operator = to the class. Is there a way to do it without change her code (copy constructor) at all? Your help...
1
by: John M. King | last post by:
Hi, I have the following code structure, where the base class's constructor takes a SomeClass pointer and stores it internally in a member. Each derived class needs to have access to that...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...

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.