Por definición, Javascript no es un lenguaje orientado a objetos, sinó orientado a prototipos. Esto solo significa que Javascript no diferencia entre Clases y Objetos, trata a ambos como parte de un objeto «prototipo» que sirve de base para crear los demás objetos.
A pesar de todo, existen implementaciones que nos permiten usar este paradigma o metodología con simulaciones desarrolladas en el propio lenguaje.
1) Joose-js
Joose-js, es quizás la librería más nueva que nos permite utilizar esta metodología, capaz de dotarnos de Clases, Herencia,… funcional en todos los navegadores.
Demo
// Create a class called Point
Class("Point", {
has: {
x: {
is: "rw",
init: 0
},
y: {
is: "rw",
init: 0
}
},
methods: {
clear: function () {
this.setX(0);
this.setY(0);
}
}
})
// Use the class
var point = new Point();
point.setX(10)
point.setY(20);
point.clear();
2) Prototype
Prototype es uno de los primeros frameworks JS que incorporaban esta posibilidad y que extendía los elementos que lo componían de esta forma.
Demo
var Animal = Class.create({
initialize: function(name, sound) {
this.name = name;
this.sound = sound;
},
speak: function() {
alert(this.name + " says: " + this.sound + "!");
}
});
// subclassing Animal
var Snake = Class.create(Animal, {
initialize: function($super, name) {
$super(name, 'hissssssssss');
}
});
var ringneck = new Snake("Ringneck");
ringneck.speak();
//-> alerts "Ringneck says: hissssssssss!"
3) Base2
Base2, el framework desarrollado por Dean Edwards, es (sinó recuerdo mal) la primera implementación de este tipo en un framework JS.
Demo
var Animal = Base.extend({
constructor: function(name) {
this.name = name;
},
name: "",
eat: function() {
this.say("Yum!");
},
say: function(message) {
alert(this.name + ": " + message);
}
});
4) MooTools
MooTools, apareció hace 2 años (casi 3) y desde que nació apostó por esta metodología. Su código está desarrollado mediante Clases que se encargan de extender todos los objetos nativos del lenguaje.
Demo
var Cat = new Class({
initialize: function(name){
this.name = name;
}
});
var myCat = new Cat('Micia');
alert(myCat.name); //alerts 'Micia'
var Cow = new Class({
initialize: function(){
alert('moooo');
}
});
var Effie = new Cow($empty);
5) Simple Javascript Inheritance
John Resig publicó hace unos meses un sistema de tan solo 25 líneas para conseguir generar clases con sus respectivos objetos.
Código
(function(){
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function(){};
// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
Demo
var Person = Class.extend({
init: function(isDancing){
this.dancing = isDancing;
}
});
var Ninja = Person.extend({
init: function(){
this._super( false );
}
});
var p = new Person(true);
p.dancing; // => true
var n = new Ninja();
n.dancing; // => false
6) Class2k (osea una versión que he montado yo)
El nombre lo he puesto por poner algo, y el código lo he extraido de MooTools 1.11. Considero que es una implementación muy limpia y sin duda nos permite crear clases con sus objetos. Lo he portado para usarse con extend() y nos permite orientar a objetos nuestro código con solo 61 líneas.
Código
function extend(opt, el){
var el = el || this;
for (var property in opt) el[property] = opt[property];
return el;
};
function type(el, type){ return (el instanceof type);}
function merge(){
var mix = {};
for (var i = 0; i < arguments.length; i++){
for (var property in arguments[i]){
var ap = arguments[i][property];
var mp = mix[property];
if (mp && type(ap, Object) && type(mp, Object)) mix[property] = merge(mp, ap);
else mix[property] = ap;
}
}
return mix;
};
var Class = function(properties){
var klass = function(){
return (arguments[0] !== null && this.initialize && type(this.initialize, Function)) ? this.initialize.apply(this, arguments) : this;
};
extend(this, klass);
klass.prototype = properties;
klass.constructor = Class;
return klass;
};
extend({
empty: function(){},
extend: function(properties){
var proto = new this(null);
var Merge = function(previous, current){
if (previous && previous != current){
if (current.constructor != previous.constructor) return current;
switch(current.constructor){
case Function:
var merged = function(){
this.parent = arguments.callee.parent;
return current.apply(this, arguments);
};
merged.parent = previous;
return merged;
case Object: return merge(previous, current);
}
}
return current;
};
for (var property in properties){
var pp = proto[property];
proto[property] = Merge(pp, properties[property]);
}
return new Class(proto);
},
implement: function(){
for (var i = 0, l = arguments.length; i < l; i++)
extend(arguments[i],this.prototype);
},
}, Class.prototype);
Demo
var Animal = new Class({
initialize: function(age){
this.age = age;
}
});
var Cat = Animal.extend({
initialize: function(name, age){
this.parent(age); //will call the previous initialize;
this.name = name;
}
});
var myCat = new Cat('Micia', 20);
alert(myCat.name); //alerts 'Micia'
alert(myCat.age); //alerts 20
¿Y tu que? ¿Usas la Orientación a Objetos en tu código Javascript?
4 comentarios, 2 referencias
+
#