Curiosidades de Javascript: Formas de invocar funciones (Parte 1)

¡Hola frikazos de la informática!

Me llamo David González Shannon, soy medio español medio americano alocado, ingeniero informático (en realidad soy ingeniero multimedia), friki y amante de la programación.

En septiembre de 2013, empecé a trabajar en Devinet como el Wildcard de la empresa, en castellano, la navaja suiza. Al no estar especializado en ninguna tecnología en concreto, pero sí estar al día de todas las novedades tecnológicas, me ha tocado trabajar de: el que se dedica a lo que no se dedican los demás (hay que hacerse útil). Eso significa que me tengo que adaptar, con la mayor rapidez posible, a cualquier proyecto que requiera una tecnología que desconozcamos. Y precisamente, una de estas tecnologías es Javascript.

Personalmente, como vengo del mundo de los lenguajes compilados como C, C++, Objective-C, C#…, los lenguajes dinámicos como Javascript me fascinan, y este concretamente me fascina tanto que he decidido escribir sobre lo que voy aprendiendo del lenguaje. Más que nada, para no olvidarme de ello y, a la vez, poder ayudar a algún internauta perdido como yo.

Este artículo trata sobre las diferentes formas que hay de invocar funciones en Javascript, un tema que me pareció muy curioso cuando lo aprendí; y esta orientado a gente que tenga nociones básicas de programación y de programación orientada a objetos. Si no es vuestro caso, aprended a programar! En serio, os estáis perdiendo horas y horas de diversión. Aquí tenéis un enlace a Codeacademy http://www.codecademy.com , una web que os enseñará a programar en varios lenguajes dinámicos (Javascript, Python, Ruby), y una imagen de un gato tocando el piano:

Gato tocando piano.

Como he dicho antes, horas de diversión!

Antes de que siga, he de mencionar que lo que estoy explicando se aplica a Javascript en el navegador, para los que programáis en node.js, ya sabéis que las cosas son un poco diferentes. Bueno, empecemos.

Hay cuatro formas de llamar a funciones en javascript, pero antes de explicarlas he de hacer una pequeña introducción a cómo son las funciones en Javascript. Todas las funciones en Javascript son Objetos y como tales se pueden asignar a variables, pasar como parámetros a otras funciones, incluso crear dentro de funciones. Cuando programas en Javascript, lo más normal es pasar como parámetro a una función otra función, que a su vez tiene una función dentro, que tiene un callback que devuelve una función, que es guardada por la función anterior y es asignada como callback a otra…

Need to go deeper, INCEPTION

Vuelve a mirar la foto del gato… ya? Sigamos pues.

Además de ser objetos, todas las funciones en Javascript reciben dos parámetros ocultos, this, que contiene el contexto de la función, y arguments, que es una especie de array (digo especie porque no es una instancia de la clase Array, es una cosa rara). Pues bien, las cuatro formas de llamar a funciones en Javascript se distinguen según el valor que recibe this, y son: como método, como función normal y «corriente» (nada es corriente en Javascript), como constructor y con la función apply.

Como método

El término método debería sonarle a todo el mundo que ha programado orientado a objetos, es simplemente el nombre que recibe la función de una clase. La diferencia con Javascript es que, aunque sea orientado a objetos, no existen clases…

Tu. WTF!?

No existen clases porque tiene prototipos, otro paradigma de programación conocido por poca gente. Aún así, en Javascript, toda función que exista como propiedad de un objeto, se considera como método por convención. Por ejemplo:

// Creo un Objeto llamado superSayan con dos propiedades:
// grito que es un string y grita que es una función

var superSayan = {
    grito: "Kamehamehaaaa!!!!",
    grita: function () {
        console.log(this.grito);
    }
}

superSayan.grita(); // En consola sale "Kamehamehaaaa!!!!"

Como podemos ver, si llamamos a las funciones de esta forma, this te da acceso a las propiedades del Objeto al que pertenece la función, por lo tanto, this es el Objeto en sí, en este caso superSayan.

 

Como función normal y «corriente»

Cuando creas una función normal y corriente sin asignarla a un Objeto ni nada, piensas «yuhuuuu! mi función es libre al fin!», y yo te digo «Mentira, sigue formando parte de The Matrix», y tu respondes con un «Nooo! Quien soy… qué es real… es aire lo que respiro…?», y acabas en un estado de shock por haber estado viviendo una mentira toda tu vida.

This is too much

En realidad, cuando creas una función suelta por el código, lo que estás haciendo es añadirla como propiedad del Objeto global, la windowEsto incluso ocurre cuando creas una función dentro de un método.

var gritoSuperSayan = "Kamehamehaaaa de la window!!!!";
function kameHameHaSuelto () {
    return "Soy libre!";
}

var superSayan = {
    grito: "Kamehamehaaaa de superSayan!!!!",
    grita: function () {
        var helper = function () {
            console.log(this.gritoSuperSayan);
            console.log(this.kameHameHaSuelto());
            console.log(this.superSayan.grito);
        }
        helper();
    }
}

console.log('Tiene la window la propiedad superSayan? ', window.hasOwnProperty('superSayan'));
// true
console.log('Tiene la window la propiedad gritoSuperSayan? ', window.hasOwnProperty('gritoSuperSayan'));
// true
console.log('Tiene la window la propiedad kameHameHaSuelto? ', window.hasOwnProperty('kameHameHaSuelto'));
// true

superSayan.grita();
// Output:
// Kamehamehaaaa de la window!!!!
// Soy libre!
// Kamehamehaaaa de superSayan!!!!

Esto es un problema de diseño de javascript en sí como lenguage,  pero si se tiene en cuenta, no resulta un problema grave. Para los que estamos acostumbrados a que this siempre haga referencia al contexto en el que estás, hay una trampilla muy simple que usan los programadores de Javascript.

var superSayan = {
    grito: "Kamehamehaaaa de superSayan!!!!",
    grita: function () {
        var that = this;
        var helper = function () {
            console.log(that.grito);
        }
        helper();
    }
}

superSayan.grita();
// Output:
// Kamehamehaaaa de superSayan!!!!

Como podemos ver, usan una variable, que por convención llaman that, en la que almacenan el this deseado. Menos mal que este artículo está escrito en castellano! Sino esto sería un poco lioso.

Bueno, de momento eso es todo amigos. En la parte 2 del artículo acabaré de explicar las otras dos formas de invocar funciones en javascript. Mientras tanto, si estáis interesados en aprender Javascript y ya sois programadores, hay un libro que me ha estado ayudando mucho y que lo recomiendan todos los programadores expertos de Javascript, se llama «Javascript: The Good Parts» y esta escrito por Douglas Crockford, un gurú de la programación. Si vais a su web, veréis una foto de él con Chuck Norris de fondo que inmediatamente te dice «este tío sabe de lo que habla».

En fin, si tenéis preguntas o comentarios que hacer, por favor hacedlo en la sección de abajo o podéis mandarme un email a [email protected].

¡Hasta la próxima frikazos de la informática!

3 comentarios en “Curiosidades de Javascript: Formas de invocar funciones (Parte 1)”

Deja un comentario