473,320 Members | 1,695 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,320 software developers and data experts.

Are multiple "constructors" allowed in JavaScript?

I have a question: I was wondering if it is possible to simulate the
multiple constructors, like in Java (yes, I know that the languages are
completely different)?

Let's say that I have a class called "Point" which would have two
values "x" and "y".

Now, let's say if it were the Java version, I would want two
constructors: one that accept two numbers, the other accepts a string:

public class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point(String coord) {
this.x = coord.charAt(0);
this.y = coord.charAt(1);
}
...
}
In JavaScript, so far I have

Point = function() {
var x;
var y;
...
}

Is it possible to have two declarations for the Point.prototype.init?
Is it even possible to have multiple constructors in JavaScript?

Thanks for the help, Andy

Dec 8 '06 #1
7 16504
VK

andrewfse...@gmail.com wrote:
I have a question: I was wondering if it is possible to simulate the
multiple constructors, like in Java (yes, I know that the languages are
completely different)?

Let's say that I have a class called "Point" which would have two
values "x" and "y".

Now, let's say if it were the Java version, I would want two
constructors: one that accept two numbers, the other accepts a string:

public class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point(String coord) {
this.x = coord.charAt(0);
this.y = coord.charAt(1);
}
...
}
In JavaScript, so far I have

Point = function() {
var x;
var y;
...
}

Is it possible to have two declarations for the Point.prototype.init?
Is it even possible to have multiple constructors in JavaScript?
What you want shall be called "polymorphic function-constructor". As
you properly noticed, a polymorphic constructor (in any language) is in
fact two or more constructors "hidden" under one common interface
(explicit in JavaScript or implicit in Java). The rest gets simple:

<script type="text/javascript">
function Point() {
switch (typeof arguments[0]) {
case 'number' : Point.$int.apply(this, arguments); break;
case 'string' : Point.$str.apply(this, arguments); break;
case 'object' : Point.$obj.apply(this, arguments); break;
default : /*NOP*/
}
}

Point.$int = function(x, y) {
this.x = x;
this.y = y;
};

Point.$str = function(coord) {
this.x = parseInt(coord.charAt(0), 10);
this.y = parseInt(coord.charAt(0), 10);
}

Point.$obj = function(obj) {
this.x = obj.x;
this.y = obj.y;
}

var p1 = new Point(2,2);
var p2 = new Point('22');
var p3 = new Point({x:2, y:2});

alert(p1.x); alert(p1 instanceof Point);
alert(p2.x); alert(p2 instanceof Point);
alert(p3.x); alert(p3 instanceof Point);
</script>

Needless to say that the arguments check for validity has to be added;
also "coord.charAt" is good only for a quick'n'durty demo (or if
guaranteed 0-9 coords range).

Dec 8 '06 #2
VK,
Thank you very much for your response. Very helpful.
also "coord.charAt" is good only for a quick'n'durty demo (or if
guaranteed 0-9 coords range).
And yes, the string-construct was just a quick-and-dirty sample to get
the point across on this post; it will be much fuller...

Dec 9 '06 #3
VK wrote:
andrewfse...@gmail.com wrote:
>I have a question: I was wondering if it is possible to
simulate the multiple constructors, like in Java (yes,
I know that the languages are completely different)?

Let's say that I have a class called "Point" which would
have two values "x" and "y".

Now, let's say if it were the Java version, I would want
two constructors: one that accept two numbers, the other
accepts a string:

public class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point(String coord) {
this.x = coord.charAt(0);
this.y = coord.charAt(1);
}
...
}
In JavaScript, so far I have

Point = function() {
That may as well be:-

function Point() {

- as that function declaration will have precisely the same result as
the assignment of a function expression to an undeclared Identifier, but
the function object will be created sooner (during variable
instantiation for the global execution context, and it will not be
possible to delete the - Point - property of the global object (though
it is extremely unlikely that anyone would attempt that anyway).

I would also be expecting to see declared formal parameters. Javascript
doesn't care about the type of arguments passed to any of its functions,
or whether all or any arguments are passed at all (defaulting unused
parameters to undefined id they are not used).
> var x;
var y;
...
}

Is it possible to have two declarations for the
Point.prototype.init? Is it even possible to have
multiple constructors in JavaScript?

What you want shall be called "polymorphic function-constructor".
As you properly noticed, a polymorphic constructor (in any
language) is in fact two or more constructors "hidden" under
one common interface (explicit in JavaScript or implicit in
Java). The rest gets simple:

<script type="text/javascript">
function Point() {
switch (typeof arguments[0]) {
case 'number' : Point.$int.apply(this, arguments); break;
case 'string' : Point.$str.apply(this, arguments); break;
case 'object' : Point.$obj.apply(this, arguments); break;
default : /*NOP*/
}
}

Point.$int = function(x, y) {
this.x = x;
this.y = y;
};

Point.$str = function(coord) {
this.x = parseInt(coord.charAt(0), 10);
this.y = parseInt(coord.charAt(0), 10);
}

Point.$obj = function(obj) {
this.x = obj.x;
this.y = obj.y;
}
Yet another pig's ear of an implementation from the VK school of never
understanding javascript well enough to do what is natural in the
language. In javascript you would naturally write such an object as:-

function Point(a, b){
switch(typeof a){
case 'number':
this.set(a, b);
break;
case 'string':
this.setWithString(a);
break;
case 'object':
this.setWithPoint(a);
break;
default:
break;
}
}
Point.prototype.x = NaN; //or some other default value like zero.
Point.prototype.y = NaN;

Point.prototype.set = function(x, y){
this.x = x;
this.y = y;
};

Point.prototype.setWithString = function(coord){
this.x = Number(coord.charAt(0));
this.y = Number(coord.charAt(1));
};

Point.prototype.setWithPoint = function(point){
this.x = point.x;
this.y = point.y;
};

- and so avoid having ragged and useless methods (could never be used as
methods of the constructor function object) hanging off the constructor
function, avoid the unnecessary dependency on -
Function.prototype.apply -(which designs out compatibility with JScript
versions prior to 5.6 at a stroke, for no real reason), avoids the
overheads in using - Function.prototype.apply -, and provides the -
Point - object instances with a group of 'setter' methods that may be
useful in modifying/updating/transforming those objects.

So that is: smaller, faster, clearer, cleaner, more widely compatible
and resulting in an object with more useful features.
var p1 = new Point(2,2);
var p2 = new Point('22');
var p3 = new Point({x:2, y:2});

alert(p1.x); alert(p1 instanceof Point);
alert(p2.x); alert(p2 instanceof Point);
alert(p3.x); alert(p3 instanceof Point);
</script>

Needless to say that the arguments check for validity has to
be added; also "coord.charAt" is good only for a
quick'n'durty demo (or if guaranteed 0-9 coords range).
It might still have been an idea not to use index zero with - charAt -
to set both - x - and - y - coordinates.

Richard.
Dec 9 '06 #4
In article <11*********************@f1g2000cwa.googlegroups.c om>,
an**********@gmail.com writes
>I have a question: I was wondering if it is possible to simulate the
multiple constructors, like in Java (yes, I know that the languages are
completely different)?
<snip>

There's nothing wrong with having several constructors with different
names for the same 'class' of objects, provided their prototype
properties are given the same value and new objects are given the right
properties. The advantage is that each constructor is cleaner. You don't
have to test the number and type of the parameters (that's not very OO,
is it).

There's nothing new or strange about this. It's the way Borland's Turbo
Pascal did it.

John
--
John Harris
Dec 9 '06 #5
VK
Richard Cornford wrote:
function Point(a, b){
switch(typeof a){
case 'number':
this.set(a, b);
break;
case 'string':
this.setWithString(a);
break;
case 'object':
this.setWithPoint(a);
break;
default:
break;
}
}
Point.prototype.x = NaN; //or some other default value like zero.
Point.prototype.y = NaN;

Point.prototype.set = function(x, y){
this.x = x;
this.y = y;
};

Point.prototype.setWithString = function(coord){
this.x = Number(coord.charAt(0));
this.y = Number(coord.charAt(1));
};

Point.prototype.setWithPoint = function(point){
this.x = point.x;
this.y = point.y;
};
That is another viable approach. What I don't like in it (doesn't mean
others have to share my feelings) - is that "obfuscates" the
inheritance chain.
Polymorphism is a horizontal process: from the entry point it goes
left, right or straight depending on arguments. Inheritance is a
vertical process (from parent to parent). This way I don't see useful
to enforce "vertical onto horizontal". As the result each Point
instance is getting a full set of sub-constructors from its constructor
with future possible fanny actions like:
var p = new Point(2, 2);
var foo = new p.set(22, 22);
// foo has nothing to do with Point if anyone wonders.

So it's a bit like gluing on each newly born chicken the leftovers of
its egg - IMHO.

Full disclosure: that's a historical moment when I do agree with John G
Harris :-) I think that polymorphism in the programming is more of an
esthetical mannerism (see my cool vs. lame notes) rather than something
technically needed.
That is not to target to OP: please take it as an overall consideration.

Dec 9 '06 #6
VK wrote:
Richard Cornford wrote:
>function Point(a, b){
switch(typeof a){
case 'number':
this.set(a, b);
break;
case 'string':
this.setWithString(a);
break;
case 'object':
this.setWithPoint(a);
break;
default:
break;
}
}
Point.prototype.x = NaN; //or some other default value like zero.
Point.prototype.y = NaN;

Point.prototype.set = function(x, y){
this.x = x;
this.y = y;
};

Point.prototype.setWithString = function(coord){
this.x = Number(coord.charAt(0));
this.y = Number(coord.charAt(1));
};

Point.prototype.setWithPoint = function(point){
this.x = point.x;
this.y = point.y;
};

That is another viable approach.
So that garbage you posted is justified once again by your claim that it
"works", regardless of drunkenly it staggers while doing so?
What I don't like in it (doesn't mean
others have to share my feelings)
It would be amazing (and very unfortunate for them) if anyone else did.
- is that "obfuscates" the inheritance chain.
And how do you propose it is doing that? We understand that you are only
just becoming aware of prototypes in javascript and their significance
in inheritance, but that just means that what you may perceive as
obscure reflects only your very limited comprehension of the language.
Polymorphism is a horizontal process: from the entry point
it goes left, right or straight depending on arguments.
Inheritance is a vertical process (from parent to parent).
This way I don't see useful to enforce "vertical onto
horizontal".
What you don't see is a matter of no interest, particularly as it
results in your writing irrelevancies like that.

I have written one 'class' definition with a constructor that can take a
number of types of argument. That is all, and it is precisely what you
did, except your version was not informed by an understanding of
javascript.
As the result each Point instance is getting a full
set of sub-constructors from its constructor
Rubbish. Each - Point - instance is being defined with a set of 'setter'
methods. Those methods happen to be being employed by its contractor,
but there is no reason for not doing that.

"setter" (and "getter") methods are familiar concepts in OO programming,
and the OP will certainly have no trouble relating them directly to what
he has previously seen in Java. While your ragged collection of methods
of the constructor that can only be sensibly used with the -
apply/call - methods only pile needless complexity on the subject. They
are more a source of 'obfuscation' than anything I have written.
with future possible fanny actions like:
var p = new Point(2, 2);
var foo = new p.set(22, 22);
You blithering idiot. I know that you program without any understanding
of what the code you write is actually doing, and so might do something
as stupid as using the - new - operator on a function that is referred
to by the name "set" just because you can (and it will "work", by some
very broad definition of the word), but do you really think any real
programmers (and particularly experienced OO programmers) are going to
do anything so obviously stupid?
// foo has nothing to do with Point if anyone wonders.
And - p.set - is so obviously not intended to be used as a constructor
that nobody would expect it to.
So it's a bit like gluing on each newly born chicken the
leftovers of its egg - IMHO.
It is opinions like that that justify the observation that your opinions
are universally worthless.
Full disclosure: that's a historical moment when I do agree
with John G Harris :-)
You may think you do, but it is more likely that you did not understand
him.
I think that polymorphism in the programming is more of
an esthetical mannerism (see my cool vs. lame notes) rather
than something technically needed. That is not to target
to OP: please take it as an overall consideration.
That loose aggregation of words does not say one way or the other.

Richard.
Dec 10 '06 #7
VK
What I don't like in it (doesn't mean
others have to share my feelings)
- is that "obfuscates" the inheritance chain.
And how do you propose it is doing that?
In the way it supposes - IMHO - to be: if one really made her mind to
have a polymorphic constructor then she also should provide polymorphic
setter to the instances.

It doesn't prohibit using the native prototype mechanics: it even may
add some more elegance to the code (but no more effectiveness):

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

function Point() {
this.set.apply(this, arguments);
}

Point.prototype.set = function() {
/* Arguments check is ommited
* in this sample for simplicity
*/
if (this instanceof Point) {
switch (typeof arguments[0]) {
case 'number':
this.x = arguments[0];
this.y = arguments[1];
break;
case 'object':
this.x = arguments[0]['x'];
this.y = arguments[0]['y'];
break;
default:
throw new Error('Illegal arguments : Point.set()');
}
}
else {
throw new Error('Illegal method call : Point.set()');
}
}

var p = new Point(2, 2);
alert(p.y);

p.set(3, 3);
alert(p.y);

p.set({x:4, y:4});
alert(p.y);

try {
p.set('foo');
}
catch(e) {
alert(e.message);
}

try {
var pp = new p.set(1, 1);
}
catch(e) {
alert(e.message);
}
</script>
</head>
<body>
</body>
</html>
We understand that you are only
just becoming aware of prototypes in javascript
Funny enough it is exactly my impression about you ;-)

<http://groups.google.com/group/comp.lang.javascript/msg/c7abb8fdbb341f56>

<snip>

Dec 10 '06 #8

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

Similar topics

7
by: Bennett Haselton | last post by:
Is there any way to find a string representing an object's class, which will work in Internet Explorer 6? "typeof" doesn't work -- it returns "object" for all objects: x =...
9
by: Player | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello all. I am in the process of teaching myself C# and I think I am doing OK. I have learnt how to how to call the right constructor of a...
10
by: Pantokrator | last post by:
Hi, Is there any way to "overload" a struct? e.g. having already struct stA1 { int i_ID; int i_Type; };
5
by: Frederick Gotham | last post by:
If we have a simple class such as follows: #include <string> struct MyStruct { std::string member; MyStruct(unsigned const i) {
37
by: jht5945 | last post by:
For example I wrote a function: function Func() { // do something } we can call it like: var obj = new Func(); // call it as a constructor or var result = Func(); // call it as...
10
by: Angel Tsankov | last post by:
Hello! Is the following code illformed or does it yield undefined behaviour: class a {}; class b {
13
by: learning | last post by:
Hi I have a static class written by other team which encapsulates a database instance. but I need to extend it to incldue other things. I know that C# static class is sealed and can;t be inherited...
2
by: Christof Warlich | last post by:
Hi, I'd like to define a class that should behave as much as posible like std::string, but that has some small additional property: class ExtendedString: public std::string { public: void...
30
by: kj | last post by:
My book (Flanagan's JavaScript: The Definitive Guide, 5th ed.) implies on page 111 that the following two constructs are equivalent: ( x.constructor == Foo ) and ( x instanceof Foo ) The...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.