Contenido

extend(), extendiendo las posibilidades de Javascript

1 dic

+ 7

Estoy haciendo limpieza de los borradores, así que es posible que estos artículos sean un poco antiguos, pero no por ello dejan de ser interesantes.

Todos los frameworks JS, basan su funcionalidad en extender elementos/objetos, pero ¿como lo hacen?. Cada uno de ellos lo enmascara de una forma, pero al final todo recae en un simple funcíon.

function extend(m, e){
    var e = e || this;
    for (var x in m) e[x] = m[x];
    return e;
};

Esta simple función, nos permite hacer cosas como estas:

var listado = [1,2,3,4,5,6,7];

// Extendemos únicamente la variable listado
extend({
	each: function(fun){
		if (typeof fun != "function") throw new TypeError();
	  for (var i = 0; i < this.length; i++) {
	    if (i in this) fun.call(arguments[1], this[i], i)
	  }
	  return this;
	}
}, listado); 

listado.each(function(el){ alert(el); });

// Extendemos todos los Arrays
extend({
	each: function(fun){
		if (typeof fun != "function") throw new TypeError();
	  for (var i = 0; i < this.length; i++) {
	    if (i in this) fun.call(arguments[1], this[i], i)
	  }
	  return this;
	}
}, Array.prototype);

new Array("hola", "adios", "buenas").each(function(el){alert(el);})

Veamos un caso práctico

Un caso que podría ayudarnos considerablemente podría ser este:

function extend(m, e){
    var e = e || this;
    for (var x in m) e[x] = m[x];
    return e;
};
// Añadimos extend a la vieja usanza
HTMLElement.prototype.extend = extend;
// o usando extend()
extend({extend: extend}, HTMLElement.prototype);

// Creamos un nuevo elemento <div />
var newEl = document.createElement("div");
// Extendemos el nuevo Elemento
newEl.extend({
	remove: function(){
	  if(!this.parentNode) return this;
      this.parentNode.removeChild(this);
	}
});

// Ahora podemos eliminarlo más fácilmente
newEl.remove();

¿Por que los parámetros así?

function extend(m[metodos], e[elemento]){}

Si nos fijamos en la declaración de la función, vemos que los parámetros son requeridos en un orden concreto, ¿por que?. El orden de los parámetros en esta función y en la funcionalidad que aplica a los elementos es crucial ya que dependiendo de él podemos hacer que nuestra función sirva para extender un elemento concreto, pasado por parámetro, o extender un elemento que contenga el método extend() como propio.

// Extendemos un elemento concreto
extend({
	metodo1: accion1,
	metodo2: accion2,
	...
}, elementoaextender);

// o al elementopropio
elementoconextend.extend({
	metodo1: accion1,
	metodo2: accion2,
	...
});

¿Y la gracia de todo esto? Pues es una simple línea:

  var e = e || this;

Esta simple línea, nos devuelve e en caso de ser e (el pasado por parámetro) válido en ese caso nos devuelve this, que hace referencia al elemento que ejecuta la función.

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.