Last active
December 11, 2015 00:19
-
-
Save yeikos/4515882 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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