Javascript: Usare apply per passare vari argomenti a un costruttore.
Lunedì, Marzo 31st, 2008Apply come già sicuramente saprete permette di passare degli argomenti ad una funzione sotto forma di array; tra l’altro lo stesso apply permette di specificare l’oggetto contesto della funzione, in altra parole l’oggetto che si potrà richiamare mediante l’operatore this.
for(var i = 0, l = arguments.length; i!=l; i++) {
this[i] = arguments[i] + "xyz";
}
}
fn.apply([], ["a", "b", "c"]);
Qualcuno si sarà chiesto se sia possibile usare apply con i costruttori, qualcuno magari avrà provato anche a scrivere il seguente codice ricevendo in cambio l’errore “xxx is not a constructor”:
this.method = function() {
}
this.str = arguments[0] || ”;
}
new miaClasse.apply(null, ["str"]) //Attenzione, questo codice NON funziona!!!
Fortunatamente non è molto difficile arrivare a una prima soluzione:
Resta ancora un problema: il codice all’interno della classe miaClasse viene eseguito inutilmente due volte, e tra l’altro a causa dell’assenza di argomenti non è detto che non possa causare un errore.
La soluzione è quella di creare un’altra classe che erediti le proprietà dalla classe originaria e usare l’oggetto creato con questa classe:
miaClasse.apply(new this, arguments)
}
function intermediate() {
}
intermediate.prototype = miaClasse.prototype;
klass.prototype = new intermediate;
//Esempio
klass.apply(null, [/*arguments…*/])
Notare che la proprietà constructor non viene corretta ( solitamente lo si fa in ogni ereditarietà ) proprio perchè potrebbe essere utile considerare l’oggetto restituito da miaClasse come se fosse un’istanza di miaClasse invece che di klass.
Infine come buona norma astrattizziamo il codice e trasformiamolo in funzione, anzi, visto che ci siamo che ne dite di un prototipo con un bel lazy pattern?
var this_ = this;
function klass() {
this_.apply(new this, arguments[0])
}
function intermediate() {
}
intermediate.prototype = miaClasse.prototype;
klass.prototype = new intermediate;
this_.instance = klass;
this_.instance(args);
}
Enjoy ![]()
