Using the arguments object when instantiating via constructor function

Discussion in 'Javascript' started by Matt Eberts, Oct 31, 2003.

  1. Matt Eberts

    Matt Eberts Guest

    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
     
    Matt Eberts, Oct 31, 2003
    #1
    1. Advertising

  2. > 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.
     
    Douglas Crockford, Oct 31, 2003
    #2
    1. Advertising

  3. Matt Eberts

    Matt Eberts Guest

    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
     
    Matt Eberts, Oct 31, 2003
    #3
  4. Re: Using the arguments object when instantiating via constructorfunction

    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
     
    Laurent Bugnion, GalaSoft, Oct 31, 2003
    #4
  5. Matt Eberts

    Dom Leonard Guest

    Re: Using the arguments object when instantiating via constructorfunction

    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
     
    Dom Leonard, Oct 31, 2003
    #5
  6. Matt Eberts

    Dom Leonard Guest

    Re: Using the arguments object when instantiating via constructorfunction

    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
     
    Dom Leonard, Oct 31, 2003
    #6
  7. > 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?
     
    Douglas Crockford, Oct 31, 2003
    #7
  8. Matt Eberts

    Matt Eberts Guest

    > 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
     
    Matt Eberts, Oct 31, 2003
    #8
  9. Matt Eberts

    Dom Leonard Guest

    Re: Using the arguments object when instantiating via constructorfunction

    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
     
    Dom Leonard, Nov 1, 2003
    #9
  10. > 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.
     
    Douglas Crockford, Nov 1, 2003
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?SGFuZHkgTXVsaWE=?=

    Help!! Problem instantiating WORD object using C#.NET

    =?Utf-8?B?SGFuZHkgTXVsaWE=?=, May 31, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    2,438
    Rick Strahl [MVP]
    May 31, 2005
  2. jmborr
    Replies:
    1
    Views:
    453
    Stargaming
    Nov 3, 2007
  3. Generic Usenet Account
    Replies:
    10
    Views:
    2,341
  4. Lacrima
    Replies:
    7
    Views:
    298
    Piet van Oostrum
    May 7, 2009
  5. Handy Mulia

    Help!! Problem instantiating WORD object using C#.NET

    Handy Mulia, May 31, 2005, in forum: ASP .Net Security
    Replies:
    2
    Views:
    268
    Dominick Baier [DevelopMentor]
    May 31, 2005
Loading...

Share This Page