Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Using the arguments object when instantiating via constructor function

Reply
Thread Tools

Using the arguments object when instantiating via constructor function

 
 
Matt Eberts
Guest
Posts: n/a
 
      10-31-2003
Sorry, bad title. Anyway, is there a way to pass the arguments to an object
instantiated via a constructor using the arguments object and have it
expanded, so to speak, so that it doesn't appear as a single argument? I'm
sorry, this explanation is just atrocious, but I can't think of exactly how
to word it. Maybe an example...

Take for instance Function.apply. It takes 1-2 arguments, the first being
the object to use as the context, and the second being either an array or an
instance of the arguments object which are to be the arguments for the
function. I want to do something similar but I want to also basically use
the new operator so that I get back an object.

Here's a snippet of some of my code, maybe this will help:

function Singleton()
{
this.construct.apply(this, arguments);
}

Singleton.extend(JSClass);

Singleton.instance = null;

Singleton.getInstance = function()
{
if(!this.instance)
{
//I want to be able to combine these two lines. If I just do new
this(arguments), then the constructor
//thinks there is only one argument; the arguments object isn't
expanded.
this.instance = new this();

this.instance.construct.apply(this.instance, arguments);
}

return this.instance;
}

function Test()
{
this.construct.apply(this, arguments);
}

Test.extend(Singleton);

Test.getInstance = function()
{
return Test.supers["Singleton"].getInstance.apply(this,
arguments);
};

Test.prototype.name = null;

Test.prototype.construct = function()
{
switch(arguments.length)
{
case 0:
this.name = "Test";
break;
case 1:
this.name = arguments[0];
break;
}
};

Anyway, I hope that despite this rather terrible explanation I've somehow
managed to get my point across. Any help would be much appreciated.

Thanks.

Matt


 
Reply With Quote
 
 
 
 
Douglas Crockford
Guest
Posts: n/a
 
      10-31-2003
> Sorry, bad title. Anyway, is there a way to pass the arguments to an object
> instantiated via a constructor using the arguments object and have it
> expanded, so to speak, so that it doesn't appear as a single argument? I'm
> sorry, this explanation is just atrocious, but I can't think of exactly how
> to word it. Maybe an example...
>
> Take for instance Function.apply. It takes 1-2 arguments, the first being
> the object to use as the context, and the second being either an array or an
> instance of the arguments object which are to be the arguments for the
> function. I want to do something similar but I want to also basically use
> the new operator so that I get back an object.

....
> Anyway, I hope that despite this rather terrible explanation I've somehow
> managed to get my point across. Any help would be much appreciated.


I'm unclear on what you want to do. Can you give us a brief specification? It is
difficult to sort through your code and try to guess what its intended effect
is.

 
Reply With Quote
 
 
 
 
Matt Eberts
Guest
Posts: n/a
 
      10-31-2003
Yeah, I'm sorry, I can't think of how to say it.

Okay, you know how with the apply() method of the Function object, you could
essentially string together a function calls without knowing the arguments
actually sent to the function? Something like:

function func_1()
{
func_2.apply(arguments);
}

function func_2(foo, bar)
{
//etc
}

....

function someFunction()
{
//blah
func_1("bleh", 5);
}

I was wondering if there was essentially a way do the same kind of thing
when creating an object via a constructor function. Something like:

function func_1()
{
//If you do this, the arguments array for the constructor function has only
one argument, and that's another
//argument array. I want this to be expanded in a similar fashion to the
apply() method.
new this(arguments);
}

function TestClass()
{
this.blah = arguments[0];
this.blah2 = arguments[1];
}

function func_2()
{
func_1.apply(this, arguments);
}

function someFunction()
{
func_2("bleh", 5);
}

I still think I'm doing a horrid job explaining this, and I'm really sorry.
I just can't think of how to explain it.

Matt


 
Reply With Quote
 
Laurent Bugnion, GalaSoft
Guest
Posts: n/a
 
      10-31-2003
Hi,

Matt Eberts wrote:

> Sorry, bad title. Anyway, is there a way to pass the arguments to an object
> instantiated via a constructor using the arguments object and have it
> expanded, so to speak, so that it doesn't appear as a single argument? I'm
> sorry, this explanation is just atrocious, but I can't think of exactly how
> to word it. Maybe an example...
>
> Take for instance Function.apply. It takes 1-2 arguments, the first being
> the object to use as the context, and the second being either an array or an
> instance of the arguments object which are to be the arguments for the
> function. I want to do something similar but I want to also basically use
> the new operator so that I get back an object.


Is this what you mean?

function CTest()
{
this.m_strArg1 = "";
if ( arguments.length > 0 )
{
this.m_strArg1 = arguments[ 0 ];
}

this.m_strArg2 = "";
if ( arguments.length > 1 )
{
this.m_strArg2 = arguments[ 1 ];
}
}

CTest.prototype.alert = function()
{
alert( this.m_strArg1 + "\n" + this.m_strArg2 );
}

var oTest1 = new CTest();
oTest1.alert();

var oTest2 = new CTest( "Hello" );
oTest2.alert();

var oTest3 = new CTest( "Hello", "World" );
oTest3.alert();

Laurent
--
Laurent Bugnion, GalaSoft
Webdesign, Java, JavaScript: http://www.galasoft-LB.ch
Private/Malaysia: http://mypage.bluewin.ch/lbugnion
Support children in Calcutta: http://www.calcutta-espoir.ch

 
Reply With Quote
 
Dom Leonard
Guest
Posts: n/a
 
      10-31-2003
Matt Eberts wrote:

> Sorry, bad title. Anyway, is there a way to pass the arguments to an object
> instantiated via a constructor using the arguments object and have it
> expanded, so to speak, so that it doesn't appear as a single argument? I'm
> sorry, this explanation is just atrocious, but I can't think of exactly how
> to word it.


No, this is not directly possible in javascript. The new operator
invokes both the [[Construct]] and [[Call]] properties of the
constructor function following the "new" operator. So the line

var bar = new Foo.apply(thisObject, argumentsArray)

would attempt to create a new Function.prototype.apply object, which (in
Mozilla at least) raises an exception because apply can not be called in
isolation.

Choices of solution lie between rewriting the program with simpler
logic, adding additional logic to the constructor function - say by
testing for magic arguments or flag variables located outside the
execution context of the constructor - or creating a generalised
mechanism to effectively split [[Construct]] and [[Call]] processing in
javascript. A function to achieve the last might go:

Function.prototype.newApply = function (constructor, argsArray)
{ function dummy(){};
dummy.prototype = constructor.prototype;
var newObj = new dummy();
var obj = constructor.apply(newObj, argsArray);
if(obj && typeof obj == "object")
return obj;
return newObj;
}

The [[Call]] property of the dummy inner function is invoked, of course,
but intentionally doesn't do anything. newApply would then be called as

bar = Foo.newApply( argsArray);

or even

bar = new Foo.newApply( argsArray);

(although this would create a new object that is immediately discarded).

--

Dom


 
Reply With Quote
 
Dom Leonard
Guest
Posts: n/a
 
      10-31-2003
Whoops!

Sorry, getting tired over here... I rewrote an earlier version of
newApply as a method of Function.prototype and forgot to change the
first argument into the "this" object. Code example should read:

Function.prototype.newApply = function (argsArray)
{ function dummy(){};
dummy.prototype = this.prototype;
var newObj = new dummy();
var obj = this.apply(newObj, argsArray);
if(obj && typeof obj == "object")
return obj;
return newObj;
}

Tested in Mozilla only

--

Dom


 
Reply With Quote
 
Douglas Crockford
Guest
Posts: n/a
 
      10-31-2003
> Yeah, I'm sorry, I can't think of how to say it.
>
> Okay, you know how with the apply() method of the Function object, you could
> essentially string together a function calls without knowing the arguments
> actually sent to the function?
>
> I was wondering if there was essentially a way do the same kind of thing
> when creating an object via a constructor function. Something like:
>
> function func_1()
> {
> //If you do this, the arguments array for the constructor function has only
> one argument, and that's another
> //argument array. I want this to be expanded in a similar fashion to the
>
> I still think I'm doing a horrid job explaining this, and I'm really sorry.
> I just can't think of how to explain it.


Are you asking if it is possible to wrap a Constructor with a function that
takes an array that will be applied to the constructor?

If so, is it

var myObj = ConstructorWrapper([array]);

If so, then trivially,

function ConstructorWrapper(a) {
return Constructor(a[0], a[1], a[2], ...);
}

But from your description, I'm not sure at all that that is what you want. If
you can't describe something, how can you ever hope to implement it correctly?

 
Reply With Quote
 
Matt Eberts
Guest
Posts: n/a
 
      10-31-2003
> No, this is not directly possible in javascript. The new operator
> invokes both the [[Construct]] and [[Call]] properties of the
> constructor function following the "new" operator. So the line
>
> var bar = new Foo.apply(thisObject, argumentsArray)
>
> would attempt to create a new Function.prototype.apply object, which (in
> Mozilla at least) raises an exception because apply can not be called in
> isolation.
>


Okay, I kind of figured that it wouldn't. Thanks for the explanation.

Matt


 
Reply With Quote
 
Dom Leonard
Guest
Posts: n/a
 
      11-01-2003
Whoops squared!

After getting some sleep, I realise that the idea of calling newApply as
a method of a constructor function *and* preceding the call with a new
operator will trigger the same problem it is trying to solve, which was
to work around:

The new operator determines the object value of a following
constructor before calling it and supplying a "this" value set to a new
object. In the process, the constructor necessarily loses knowledge of
the object of which it itself may be a method.



--
Dom



 
Reply With Quote
 
Douglas Crockford
Guest
Posts: n/a
 
      11-01-2003
> Whoops squared!
>
> After getting some sleep, I realise that the idea of calling newApply as
> a method of a constructor function *and* preceding the call with a new
> operator will trigger the same problem it is trying to solve, which was
> to work around:
>
> The new operator determines the object value of a following
> constructor before calling it and supplying a "this" value set to a new
> object. In the process, the constructor necessarily loses knowledge of
> the object of which it itself may be a method.


Get some more sleep, man.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Checking for required arguments when instantiating class. Lacrima Python 7 05-07-2009 01:04 PM
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
how to pass a function name and its arguments inside the arguments of other function? jmborr Python 1 11-03-2007 08:20 AM
Help!! Problem instantiating WORD object using C#.NET Handy Mulia ASP .Net Security 2 05-31-2005 04:27 PM
Help!! Problem instantiating WORD object using C#.NET =?Utf-8?B?SGFuZHkgTXVsaWE=?= ASP .Net 1 05-31-2005 09:29 AM



Advertisments