C'est comment vous le faites:
function applyToConstructor(constructor, argArray) {
var args = [null].concat(argArray);
var factoryFunction = constructor.bind.apply(constructor, args);
return new factoryFunction();
}
var d = applyToConstructor(Date, [2008, 10, 8, 00, 16, 34, 254]);
L'appel est un peu plus facile
function callConstructor(constructor) {
var factoryFunction = constructor.bind.apply(constructor, arguments);
return new factoryFunction();
}
var d = callConstructor(Date, 2008, 10, 8, 00, 16, 34, 254);
Vous pouvez utiliser une de ces options pour créer de l'usine de fonctions:
var dateFactory = applyToConstructor.bind(null, Date)
var d = dateFactory([2008, 10, 8, 00, 16, 34, 254]);
ou
var dateFactory = callConstructor.bind(null, Date)
var d = dateFactory(2008, 10, 8, 00, 16, 34, 254);
Il fonctionne avec n'importe quel constructeur, et pas seulement built-ins ou les constructeurs qui peut doubler comme des fonctions (comme la Date).
Cependant, elle nécessite l'Ecmascript 5 .fonction de liaison. Les cales ne sera probablement pas fonctionner correctement.
Une approche différente, plus dans le style de certains des autres réponses est de créer une fonction de la version de la construite en new
. Cela ne fonctionnera pas sur tous les objets internes (comme la Date).
function neu(constructor) {
// http://www.ecma-international.org/ecma-262/5.1/#sec-13.2.2
var instance = Object.create(constructor.prototype);
var result = constructor.apply(instance, Array.prototype.slice.call(arguments, 1));
// The ECMAScript language types are Undefined, Null, Boolean, String, Number, and Object.
return (result !== null && typeof result === 'object') ? result : instance;
}
function Person(first, last) {this.first = first;this.last = last};
Person.prototype.hi = function(){console.log(this.first, this.last);};
var p = neu(Person, "Neo", "Anderson");
Et maintenant, bien sûr, vous pouvez faire .apply
ou .call
ou .bind
sur neu
comme d'habitude.
Par exemple:
var personFactory = neu.bind(null, Person);
var d = personFactory("Harry", "Potter");
Je pense que la première solution que je donne est mieux, car il ne dépend pas de vous correctement de la réplication de la sémantique d'un builtin et qu'il fonctionne correctement avec les builtins.