Hace unas semanas vimos el rendimiento que ofrecían las diferentes técnicas que proporcionan la posibilidad de añadir Orientación a Clases a nuestros scripts en Javascript.
En las pruebas realizadas por Broofa, vimos que los resultados daban como ganador al script de John Resig que dejaba a los demás a la altura del betún. Algo sorprendente en tan solo 25 líneas de código.
JotaClass
jDeveloper (o Jota) nos deleitó con jClass2k, una implementación propia que estuvimos puliendo durante unos días para intentar mejorar los resultados obtenidos.
var JotaClass = function(current,previous){
previous = typeof previous == 'undefined' ? {} : previous.prototype;
for(p in previous){
if(typeof current[p] == 'undefined') current[p] = previous[p];
else if(typeof previous[p] == 'function'){
current[p] = (function(tmp){
var _parent = function(){
this.parent = _parent.parent;
return tmp.apply(this, arguments);
}
return _parent;
})(current[p]);
current[p].parent = previous[p];
}
}
var construct = function(){
if(this.init) this.init.apply(this,arguments);
}
construct.prototype = current;
construct.constructor = JotaClass;
return construct;
}
//Modo de empleo
var Hobbit = new JotaClass({
bailar: function(){
.....
}
});
var Frodo = new JotaClass({
anillo: true;
desaparecer: function(){
if (this.anillo)
this.display("none");
}
},Hobbit);
JoseanpgClass
En este proceso Jose Antonio Perez (Joseanpg) se añadió para ilustrarnos con su experiencia y ayudarnos a pulir el script y obtener mejores resultados. A partir de ahí, salió otra implementación que podemos ver a continuación.
function makeParent(fn, parent) {
return function() {
this.parent = parent;
return fn.apply(this, arguments);
}
}
var JoseanpgClass = function(current,previous){
previous = typeof previous == 'undefined' ? {} : previous.prototype;
for(p in previous)
current[p] = (typeof previous[p] == 'function')?makeParent(current[p], previous[p]):previous[p];
var construct = function(){ if(this.init) this.init.apply(this,arguments);}
construct.prototype = current;
construct.constructor = JoseanpgClass;
return construct;
}
//Modo de empleo
var Hobbit = new JoseanpgClass({
bailar: function(){
.....
}
});
var Frodo = new JoseanpgClass({
anillo: true;
desaparecer: function(){
if (this.anillo)
this.display("none");
}
},Hobbit);
Klass
Como me dió envidia, decidí implementar mi propia versión. Basada en el script de John Resig y sacando alguna idea de los scripts anteriores.
var Klass = function(prop) {
var klass = function(){ if(this.init) this.init.apply(this, arguments);};
klass.prototype = prop || {};
klass.constructor = Klass;
klass.extend = Klass.extend;
return klass;
};
Klass.extend = function(prop){
function setParent(fn, parent) {
return function() {
this.parent = parent;
return fn.apply(this, arguments);
}
}
function merge(prev, next){
for (var name in next){
if (prev[name] && (typeof prev[name] == 'object' && typeof next[name] == 'object'))
merge(prev[name], next[name]);
else
prev[name] = next[name];
}
return prev;
};
for (var name in this.prototype) {
if (!prop[name])
prop[name] = this.prototype[name];
else if(typeof prop[name] == 'function' && typeof this.prototype[name] == 'function')
prop[name] = setParent(prop[name], this.prototype[name]);
else if(typeof prop[name] == 'object' && typeof this.prototype[name] == 'object')
prop[name] = merge(prop[name], this.prototype[name]);
}
return new Klass(prop);
};
//Modo de uso
var Hobbit = Klass({
bailar: function(){
.....
}
});
var Frodo = Hobbit.extend({
anillo: true;
desaparecer: function(){
if (this.anillo)
this.display("none");
}
});
Resultados
He montado un test basado en JSLitmus, osea que nos cuenta el número de operaciones por segundo (mientras más mejor) para testear nuestras implementaciones frente a la de John Resig (la más rápida de las anteriores). Para los que lo sepan, la versión Ad Hoc, es la montada nativamente.
Ir al test
No he podido probar en más navegadores y todo está probado sobre Mac OS. Es interesante ver como, en todas las pruebas, siempre sobrepasamos (alguna implementación) la implementación de John Resig.
Actualización
He podido probar sobre Windows con diferentes navegadores, veamos los resultados:
Firefox 3.0.7
Opera 9.63
Internet Explorer 6
Internet Explorer 7.0
Safari 4
Google Chrome
4 comentarios, 1 referencias
+
#