Passing a variable number of arguments into the a constructor beingused with the `new' keyword

A

Andrey Fedorov

Is it possible?

Example:

foo(1,2,3); /* === */ foo.apply(window, [1,2,3]);

// but

new Foo(1,2,3); /* === */ ???
 
M

Martin Rinehart

Is it possible?

Example:

foo(1,2,3);    /* === */    foo.apply(window, [1,2,3]);

// but

new Foo(1,2,3);    /* === */    ???

new Foo( [1,2,3] ); // one argument, any length
 
A

Andrey Fedorov

To properly set up the prototype you need a little more [...]

This is what I'm doing now. My problem is that then, the `constructor'
property still isn't set correctly and hence the `instanceof' operator
doesn't work. One solution I'm considering is:

function Foo(arg1, arg2, ...) {
if (!arg.length) return; // required
// rest of code
}

function new_obj(type, args) {
x = new type();
type.apply(x, [1,2,3]);
return x;
}

x = new_obj(Foo, [1,2,3]);

But I'd love to be able to avoid that starting line inside of Foo.

Martin said:
new Foo( [1,2,3] ); // one argument, any length

I don't know if you're serious, but this is actually where I'm
leaning, if I don't figure out an elegant way of doing the former.

Cheers,
Andrey
 
H

Henry

... . My problem is that then, the `constructor'
property still isn't set correctly

If you don't like the way a 'constructor' property is set then why not
set it the way you want it?
and hence the `instanceof' operator
doesn't work. ...

The - instanceof - operator does not employ, and so has no interest
in, the - constructor - properties of objects. The instance of
operator makes an assertion about the runtime relationship between the
value assigned to the - prototype - property of a function and the
objects on the prototype chain of an object (produces a true result if
the function's prototype property value at that time is the same
object as one of the objects on the prototype chain of the operand
object).
 
L

Lasse Reichstein Nielsen

Andrey Fedorov said:
Is it possible?

Example:

foo(1,2,3); /* === */ foo.apply(window, [1,2,3]);

// but

new Foo(1,2,3); /* === */ ???

No.

What you can do is to make Foo handle an array argument properly:

function Foo(yadda, yadda2) {
if (arguments.length == 1 && yadda instanceof Array) {
Foo.apply(this, yadda);
return this;
}
}

I.e., calling the constructor as a function on the new object using
apply.

/L
 
T

Thomas 'PointedEars' Lahn

Andrey said:
Is it possible?

Is *what* possible? said:
Example:

foo(1,2,3); /* === */ foo.apply(window, [1,2,3]);

// but

new Foo(1,2,3); /* === */ ???

IIUC, short of modifying Foo() to accept an Array object reference,
IMHO there is a good chance that the following worked:

var f = new Foo();
Foo.apply(f, [1, 2, 3]);

(Examples where it doesn't work this way include Date() since per
specification it ignores all arguments when [[Call]]ed rather than
[[Construct]]ed.)

Is this only a theoretical question or do you have an actual case
where you need it?


PointedEars
 
T

Thomas 'PointedEars' Lahn

Andrey said:
To properly set up the prototype you need a little more [...]

This is what I'm doing now. My problem is that then, the `constructor'
property still isn't set correctly and hence the `instanceof' operator
doesn't work. One solution I'm considering is:

function Foo(arg1, arg2, ...) {
if (!arg.length) return; // required

Probably you mean

if (!arguments.length) return; // required
// rest of code
}

function new_obj(type, args) {
x = new type();
^ ^^^^
Using `type' as an identifier is a bad idea, it might become a reserved
word. Not declaring `x' a local variable is worse, especially here:
type.apply(x, [1,2,3]); ^
return x; ^
}

x = new_obj(Foo, [1,2,3]);
^ ^
|
Identifiers for constructors should start uppercase.
But I'd love to be able to avoid that starting line inside of Foo.

Why would you want to avoid using the gauntlet? Why waste resources going
through initialization when it is doomed to fail? (Note that a constructor
call will return an object reference no matter the return value.)

Please include an attribution line for each quotation level you leave in:

<http://jibbering.com/faq/#posting>


PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
Andrey said:
function new_obj(type, args) {
x = new type();
^ ^^^^
Using `type' as an identifier is a bad idea, it might become a reserved
word. Not declaring `x' a local variable is worse, especially here:
type.apply(x, [1,2,3]); ^
return x; ^
}

x = new_obj(Foo, [1,2,3]);
^ ^
|
Identifiers for constructors should start uppercase.

new_obj() is not [[Constructed]] here, it serves as a factory. But the
recommendation would definitely apply to `type', and changing that
accordingly would address two potential problems in one step.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top