#286 enhancement
ronin-28987 (at lighthouseapp)

Construct a class with arbitrary number of arguments

Reported by ronin-28987 (at lighthouseapp) | August 16th, 2008 @ 04:45 PM | in 1.7

Adding the next piece of code to Class.Methods will make it possible to construct a class with an arbitrary number of arguments.


Class.Methods = {
  addMethods: function(source) {
    // ...
  },

  construct: function(args) {
    var init = this.prototype.initialize; // store original initialize
    this.prototype.initialize = Prototype.emptyFunction; // temporary empty initialize
    var instance = new this(); // create instance
    instance.initialize = this.prototype.initialize = init; // restore initialize
    instance.initialize.apply(instance, $A(args) ); // apply initialize
    return instance; // return new object
  }
};
// ------
// now we can use:
var someInstance = SomeClass.construct(["arg1", "arg2"]);

This can be very useful when you have "factory"-methods in which you don't need to know the number of arguments, as in:


function createClass(className) {
  var args = $A(arguments); args.shift();
  return window[className].construct(args);
}

Comments and changes to this ticket

  • Juriy Zaytsev

    Juriy Zaytsev August 16th, 2008 @ 07:04 PM

    • State changed from “new” to “enhancement”
    • Assigned user set to “Juriy Zaytsev”
    • Milestone set to 1.7

    That's clever.

    The only thing I'm not sure about is assigning of initialize property directly to an instance. This seems unnecessary and somewhat obtrusive. When "restoring" a prototype.initialize from init, why not call init directly via apply (and not assign it to an instance, but leave it on prototype as it was before)?

    
    Class.Methods.construct = function(args) {
      var init = this.prototype.initialize;
      this.prototype.initialize = Prototype.emptyFunction;
      var instance = new this();
      this.prototype.initialize = init;
      init.apply(instance, $A(arguments.length == 1 ? args : arguments));
      return instance;
    };
    

    This also allows to optionally pass arguments the usual way, rather than explicitly passing an array:

    
    Person.construct('Ivan', 'Petrovich');
    // or
    Person.construct(['Jan', 'Kowalski']);
    
  • ronin-28987 (at lighthouseapp)

    ronin-28987 (at lighthouseapp) August 16th, 2008 @ 07:43 PM

    I agree with you on applying initialize on the instance rather than restoring it. I don't agree on the arguments length check, because it will also split the first argument when it's meant to be an array

    
    var someClass = Class.create({
      initialize: function(someArray) {
        this.someArray = someArray;
      }
    });
    var someInstance = someClass.construct(["foo", "bar"]);
    
    someInstance.someArray
    // --> foo
    // --> expected ["foo", "bar"]
    
  • Juriy Zaytsev
  • ronin-28987 (at lighthouseapp)

    ronin-28987 (at lighthouseapp) August 18th, 2008 @ 11:17 AM

    
    Class.Methods.construct = function(args) {
      var init = this.prototype.constructor;
      this.prototype.constructor = Prototype.emptyFunction;
      var instance = new this();
      this.prototype.constructor = init;
      init.apply(instance, $A(args) );
      return instance;
    };
    

    is actually more correct I think and avoids an extra call to a function

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 01:55 AM

    • Tag changed from class, enhancement, function, needs_tests to function, needs_tests, section:lang

    [not-tagged:"class" tagged:"section:lang" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:07 AM

    • Tag changed from function, needs_tests, section:lang to needs_tests, section:lang

    [not-tagged:"function" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:26 AM

    • Tag changed from needs_tests, section:lang to missing:tests, section:lang

    [not-tagged:"needs_tests" tagged:"missing:tests" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 03:36 AM

    • Tag changed from missing:tests, section:lang to needs:tests, section:lang

    [not-tagged:"missing:tests" tagged:"needs:tests" bulk edit command]

  • T.J. Crowder

    T.J. Crowder November 16th, 2009 @ 04:50 PM

    • Assigned user cleared.

    [responsible:none bulk edit command]

  • Leigh George

    Leigh George May 14th, 2018 @ 05:40 PM

    You have got such a down to earth and talented writers. One of your australiawritings me make my resume when apparently it was not an easy task. But your writer performed it brilliantly.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

The Prototype JavaScript library.

Shared Ticket Bins

People watching this ticket

Pages