VISITAS:

viernes, 9 de enero de 2015

Javascript avanzado: Funciones

Este es el primer artículo de una serie que tengo la intención de escribir sobre javascript avanzado. Empezaré por intentar explicar algunos conceptos avanzados de las funciones en javascript.

Muchos desarrolladores, cuando les preguntan ¿sabes javascript? Responden un sí inmediata y contundentemente. Yo era uno de ellos, hasta hace poco.
Muchos pensábamos que javascript se reduce a una serie de tipos básicos, condiciones if, bucles for/while y declaración de funciones. Algunos incluso hemos utilizado callbacks para eventos en páginas html.
También, muchos pensábamos que javascript se utiliza única y exclusivamente en el desarrollo web, dentro las páginas html. Efectivamente, así empezó javascript. Pero hoy en día, esto no es cierto. Javascript es un lenguaje muy avanzado y que se utiliza en muchos otros entornos además del desarrollo web, por ejemplo, en el desarrollo de aplicaciones para móvil.

Javascript es uno de los lenguajes más avanzados y expresivos que existen actualmente (esto puede sorprender a más de uno). Estas son algunas de sus características destacadas:

  • Rendimiento: Javascript utiliza compilación just-in-time, o sea, se compila y se traduce a código máquina justo antes de ejecutarse. Su rendimiento es similar al de aplicaciones escritas en C o C++. Sin embargo, javascript tiene la penalización de la recolección de basura y enlazado dinámico de tipos (las variables pueden cambiar de tipo dinámicamente).
  • Objectos: Javascript tiene características avanzadas de orientación a objetos. Utiliza el modelo de herencia con prototipos (en lugar de clases, tenemos prototipos de objetos). Este modelo es más potente y flexible que el modelo de herencia con clases utilizado en lenguajes como Java. Javascript también soporta, a pesar de ser poco conocidas, las siguientes características: encapsulación, polimorfismo, herencia múltiple y composición.
  • Sintaxis: La sintaxis de javascript es similar a la de lenguajes como C++, Java, C# o PHP. Esta es una de las causas del éxito de javascript.
  • Funciones: En javascript, casi todo son objetos, incluidas las funciones. Por este motivo, podemos usar una función en cualquier sitio en que podemos utilizar una variable (por ejemplo en un parámetro de una llamada a función). Las funciones que reciben como parámetro una función o retornan una función como resultado, se llaman funciones de alto orden.
  • Reutilización: Javascript es portable, es decir, puede ejecutarse en cualquier plataforma.
Comencemos por tanto explicando algunos conceptos, no demasiado avanzados sobre las funciones en javascript, pero que introducen los conceptos más avanzados que se explicarán posteriormente. En posteriores artículos hablaré del ámbito (scope), closures, this, prototype.

Las funciones son datos

En javascript existen los siguientes tipos:

  • PRIMITIVOS
    • Number: desde 5e-308 hasta 1e+308, Infinity, NaN
    • Boolean: true, false
    • String: "....", '....'
    • undefined: cuando una variable se declara, su valor es undefined
    • null: se puede asignar null a una variable
  • OBJECT
    • Object
    • function

Las funciones son también un dato, concretamente, Object.

var f = function(v) {
    return v+1;
}
typeof f;   // "function"


Funciones de callback

function add(f1, f2) {
    return f1() + f2();
}
var one = function() { return 1; }
var two = function() { return 2; }
add(one, two);   // 3

Funciones inmediatas

Las funciones inmediatas se ejecutan inmediatamente:

(function() {
    alert('hello');
})();

Las funciones inmediatas pueden recibir parámetros:

(function(name) {
    alert('hello '+name);
})('world');
Las funciones inmediatas se pueden utilizar para tareas de inicialización, ya que se ejecutan inmediatamente y todas sus variables locales quedan dentro, en privado.

Funciones privadas

function outer(p1) {
    function inner(p2) {
        return 2 * p2;
    }
    return 10 + inner(p1);
}

La función inner() no es accesible desde fuera.

Función que retorna una función

function a() {
    return function() { return 'A'; };
}

var f = a();   // asigna la función interna a la variable f
f();       // invoca la función interna

También se puede invocar la función interna del siguiente modo:

a()();
Se puede reasignar una función. De esta forma, la primera vez que se ejecuta la función puede realizar labores de inicialización y después su función habitual:

function f() {
    // labores iniciales
    .......
    return function() { ...... labores habituales .... };
}
f = f(); 
   
Otra forma más elegante de reasignar una función:

function a() {
    ... código que se ejecuta la primera vez
    a = function() { ... código habitual .... };
}
Y otra forma más, utilizando funciones inmediatas:

var a = (function() {
    function init() {
        .... inicialización
    }
    function work() {
        .... trabajo real
    }
    init();
    return work;
})();