Construct a class with arbitrary number of arguments
Reported by Giso Stallenberg | August 16th, 2008 @ 04:45 PM | in 1.6.1
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 August 16th, 2008 @ 07:04 PM
- → Milestone changed from to 1.6.1
- → State changed from new to enhancement
- → Assigned user changed from to Juriy Zaytsev
That's clever.
The only thing I'm not sure about is assigning of
initializeproperty directly to an instance. This seems unnecessary and somewhat obtrusive. When "restoring" aprototype.initializefrominit, why not callinitdirectly viaapply(and not assign it to an instance, but leave it onprototypeas 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']); -

Giso Stallenberg 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"] -
-

Giso Stallenberg 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
Please Login or create a free account to add a new comment.
You can update this ticket by sending an email to from your email client. (help)
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.
