Skip to content

Instantly share code, notes, and snippets.

@yeikos
Last active December 11, 2015 00:19
Show Gist options
  • Save yeikos/4515882 to your computer and use it in GitHub Desktop.
Save yeikos/4515882 to your computer and use it in GitHub Desktop.
// http://www.yeikos.com/2013/01/revitalizando-instancias-javascript.html
var Animal = (function() {
var Public = function Animal(parent, child) {
// Si no se ha creado la instancia
if (!(this instanceof Public)) // Public()
// Reiniciamos la llamada para la creación de la instancia
return Public.instance(arguments);
// Si no se encuentra el marcador `isChild` activado
if (!this.isChild)
// Añadimos una nueva instancia a la instancia padre
this.child = Public.instance([child], function() {
// Antes de llamar al constructor original
// añadimos un marcador para evitar que se vuelva
// a crear otra instancia (bucle infinito)
this.isChild = true;
});
// A continuación empieza el constructor común para todas las instancias
this.animals = [];
this.add(parent);
// Retornamos la instancia
return this;
}, publicName = 'Animal';
// Creamos el prototipo
Public.prototype = {
constructor: Public,
animals: null,
add: function(name) {
this.animals.push(name);
return this;
},
get: function() {
return this.animals.join(', ');
}
};
// Función encargada de crear una nueva instancia con dos características a destacar
// Es posible pasar los argumentos a traves de una matriz (imposible con new)
// Es posible interactuar con la instancia antes de llamar al constructor original
Public.instance = function(argv, callback) {
// Constructor temporal
var Foo = function Animal(callback) {
// Si se especificó una función
if (typeof callback === 'function')
// Le pasamos la instancia como contexto
callback.call(this);
};
// Asignamos al constructor temporal el prototipo de la función original
// Llamamos al constructor original para que opere sobre la instancia
// Retornamos la instancia devuelta por el constructor original
return (Foo.prototype = Public.prototype).constructor.apply(
new Foo(callback), argv
);
};
return Public;
})(this);
var animal = Animal('cat', 'littel cat');
console.log( animal instanceof Animal ); // true
console.log( animal.child instanceof Animal ); // true
console.log( animal.get() ); // cat
console.log( animal.child.get() ); // littel cat
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment