Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using 'apply' to construct an object

0 views
Skip to first unread message

franck

unread,
Aug 30, 2005, 11:21:14 AM8/30/05
to
Hello,

When I need to call a function with a variable list of arguments, I use :

var args = [ 111, 222, 333 ];
myFunction.apply( this, args );


Now I need to do the same thing with the constructor of an object, but I am unable to find the right syntax.
Something like this :

new myClass.apply( this, args ); // do not work !


Thanks for any help.

Franck.

Peter Wilson

unread,
Aug 30, 2005, 11:53:21 AM8/30/05
to
var newObj = new myClass(args)

No this - because it's the constructor and is provided for you. Not method name
because the class name is the constructor.

Pete
--
http://www.whitebeam.org
----

franck

unread,
Aug 30, 2005, 12:12:33 PM8/30/05
to
In fact, I want to create an object ( new myClass... ) with a variable argument list ( ...apply( xxx, myListOfArguments ) )

An alternative way to achieve this is :

new myClass( args[0], args[1], args[2], args[3], args[4], ... args[n] );

But the constructor of the object I am trying to create failed if I provide more than the expected number of arguments.

myClass is a native JSClass class ( wxDialog(Parent, Id, Title [, Position, Size, Style]) )


Franck.

Brendan Eich

unread,
Aug 30, 2005, 3:07:39 PM8/30/05
to


You are quite right that it's not possible to combine new with apply,
unfortunately. We hit this working on Narcissus
(http://lxr.mozilla.org/mozilla/source/js/narcissus/jsexec.js -- look
for __construct__).

This is something to work around for now, as you propose and as we did
for Narcissus. We'll fix it for Edition 4 / JS2.

/be

Alexis Nikichine

unread,
Aug 31, 2005, 7:49:52 AM8/31/05
to
Brendan Eich wrote:
> franck wrote:
>
>> In fact, I want to create an object ( new myClass... ) with a variable
>> argument list ( ...apply( xxx, myListOfArguments ) )
>>
>> An alternative way to achieve this is :
>>
>> new myClass( args[0], args[1], args[2], args[3], args[4], ...
>> args[n] );
>>
>> But the constructor of the object I am trying to create failed if I
>> provide more than the expected number of arguments.
>
>
> You are quite right that it's not possible to combine new with apply,
> unfortunately. We hit this working on Narcissus
> (http://lxr.mozilla.org/mozilla/source/js/narcissus/jsexec.js -- look
> for __construct__).
>
> This is something to work around for now, as you propose and as we did
> for Narcissus. We'll fix it for Edition 4 / JS2.

But let me point out that it is possible to work around it while staying
in the current language:

var constructWithArgs = (function() {
function Dummy(){ ; }// Scope-contained, "private",
// dummy constructor. No other code
// needs access to this constructor.
return (function(fun, args) {
Dummy.prototype = fun.prototype;
var tmp = new Dummy; // Internal [[Prototype]] of new
// object is set to fun.prototype
// but no other properties are
// created/changed.
fun.apply(tmp, args); // Use constructor to create/apply
// new properties to the Dummy instance,
// creating an object indistinguishable
// form one created with - fun -.
return tmp; // Return the new object
} )
})

I won't claim credits for this, but leave them to Richard Cornford in
http://groups.google.fr/group/comp.lang.javascript/msg/6e06b7884b3db6ad

Or was some flaw overlooked in this code ?

Cheers,

Alexis

--
Some domain is free

franck

unread,
Aug 31, 2005, 8:49:19 AM8/31/05
to


It's a nice work around, however the 'fun' is called, and not constructed.
I think this works perfectly with javascript ( not native ) objects.
It will failed if the native constructor looks like this:

...
JSBool NativeClassConstruct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {

if ( !JS_IsConstructing(cx) )
return JS_FALSE;

...
return JS_TRUE;
}
...


Franck.

Brendan Eich

unread,
Aug 31, 2005, 12:31:31 PM8/31/05
to Alexis Nikichine
Alexis Nikichine wrote:
> Brendan Eich wrote:
>
>> franck wrote:
>>
>>> In fact, I want to create an object ( new myClass... ) with a
>>> variable argument list ( ...apply( xxx, myListOfArguments ) )
>>>
>>> An alternative way to achieve this is :
>>>
>>> new myClass( args[0], args[1], args[2], args[3], args[4], ...
>>> args[n] );
>>>
>>> But the constructor of the object I am trying to create failed if I
>>> provide more than the expected number of arguments.
>>
>>
>>
>> You are quite right that it's not possible to combine new with apply,
>> unfortunately. We hit this working on Narcissus
>> (http://lxr.mozilla.org/mozilla/source/js/narcissus/jsexec.js -- look
>> for __construct__).
>>
>> This is something to work around for now, as you propose and as we did
>> for Narcissus. We'll fix it for Edition 4 / JS2.
>
>
> But let me point out that it is possible to work around it while staying
> in the current language:


Sure, but these are both workarounds. The way Franck and Narcissus do
it is limited to a certain number of arguments, but does a true
constructor call. The way you do it (cited below) wastes an object, but
does not have the arguments limit. Neither is ideal.

/be

0 new messages