Extendiendo objetos en JavaScript

Muchos lenguajes cuentan con la posibilidad de extender la funcionalidad de objetos nativos o creados por programadores.

Por ejemplo, en C#, podemos “inyectar” funcionalidad mediante los Extendend Methods (http://msdn.microsoft.com/en-us//library/bb383977.aspx) a objetos pre existentes. Pero es necesario remarcar que esta característica (En el caso de C#), es solo una forma de alivianarle el trabajo al desarrollador mientras escribe código, ya que por detrás, el código se ejecuta de la misma forma que lo haría si llamásemos a una función dentro de una clase estática.

Veamos un ejemplo:

class Program
{
    static void Main(string[] args)
    {
        string text = “”;
        Console.WriteLine(text.ToSomething());
        Console.WriteLine(Ext.ToSomething2(text));
        Console.ReadLine();
    }
}

public static class Ext
{
    public static string ToSomething(this string data)
    {
        return data + “Hola”;
    }

    public static string ToSomething2(string data)
    {
        return data + “Hola”;
    }
}

En este caso, si vemos el código en la clase Program, todo apuntaría a que tenemos una mejora con el método extendido, ya que no necesitaríamos conocer la función en cuestión, misma que es provista desde el tipo de dato y, por otro lado, la función “ToSomething” queda incorporada al tipo.

Pero, si miramos un poco más adentro, esto es, el código IL, veremos que en realidad, no pasa nada de nada. Todo sigue funcionando como si hubiésemos llamado a una función común.

IL_0000:  nop
IL_0001:  ldstr      “”
IL_0006:  stloc.0
IL_0007:  ldloc.0
IL_0008:  call       string Extendend.Ext::ToSomething(string)
IL_000d:  call       void [mscorlib]System.Console::WriteLine(string)
IL_0012:  nop
IL_0013:  ldloc.0
IL_0014:  call       string Extendend.Ext::ToSomething2(string)
IL_0019:  call       void [mscorlib]System.Console::WriteLine(string)
IL_001e:  nop
IL_001f:  call       string [mscorlib]System.Console::ReadLine()
IL_0024:  pop
IL_0025:  ret

O sea, no hemos enriquecido el objeto, solo hemos agregado soporte visual.

En JavaScript, por el contrario, es posible inyectar funcionalidad a los objetos y que estas sean parte del objeto, tanto para uno particular como para todas las “instancias” del mismo tipo.

Esto podemos conseguirlo con el uso de “prototype”. Pero veamos un ejemplo:

var arr = [];
//Llenamos el array


//Buscar un elemento
for (var i = 0; i < arr.length; i++) {
   if (arr[i] === …) {
     founds.push(arr[i]);
   }
}

En el ejemplo, lo que intentamos hacer es obtener un elemento de un array basados en un criterio particular. La lógica resulta simple, y podría ser encapsulada en una función y así usarse tantas veces como se requiera.

Por supuesto, podríamos hacer esto, o extender el objeto Array para que contenga esta funcionalidad.

if (Array.prototype.where === undefined) {
    Array.prototype.where = function (selector) {
        var result = [];
        for (var i = 0; i < this.length; i++) {
            if (selector(this[i])) {
                result.push(this[i]);
            }
        }
        return result;
    }
}

La principal diferencia, comparada con una función y con el ejemplo de C# es que, en este caso, efectivamente el objeto Array posee, ahora, una función llamada “where”, y cualquier instancia de Array contendrá la misma, no repitiendo el código si no, incorporándolo al objeto.

En resumen, en JavaScript, es posible modificar los objetos y tipos más allá de un cambio visual de cara al desarrollador. Esto nos otorga mayor flexibilidad para desarrollar ya que no es necesario tener un conjunto de funciones para tareas sobre objetos específicos, si no que podemos enriquecer estos objetos de forma directa.



Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s