Para poder trabajar bien con Node vamos a continuar repasando varias cosas de JavaScript, pensando sobretodo en no tener problemas con funciones o métodos complejos de Node.

Empecemos con THIS

Vamos a ver un poco para que usamos esta palabra reservada.
Tenemos dos casos típicos donde nos podemos encontrar this:

  • El primero sería dentro de un método o función. En este caso this haría referencia a la instanciación de ese método, veamos un ejemplo:
var superhero = {
  name: 'Jonathan Osterman',
  alias: 'Dr. Manhattan',
  getInfo: function() {
     console.log(this.name + ' se convirtió en el ' + this.alias);
   }
}
superhero.getInfo();

Como veis usamos this para acceder a los datos dentro de superhero cuando llamamos a la función getInfo, sin this obtendríamos este error
This error
Sin this no tenemos acceso al contexto en el que estamos funcionando.

  • El segundo caso es cuando lo usamos fuera de un método. En este caso this tendria la información del contexto global o si estamos en modo estricto que seria undefined (cuando ponemos 'use strict' al inicio de nuestra clase teneis info aqui Modo Estricto)
    Veamos un ejemplo(sin modo estricto)
var superhero = {}
this.superhero = {
  name: 'Jonathan Osterman',
  alias: 'Dr. Manhattan',
  getInfo: function () {
     console.log(this.name + ' se convirtió en el ' + this.alias)
   }

}

console.log(this)

En este caso hemos introducido en el this del contexto global la propiedad superhero, que al hacerlo así tenemos que declararla primero, y si vemos el resultado vemos como ahora this tiene ese objeto
global this example
Si lo ejecutaramos en un navegador veríamos como this en el contexto global contiene el objeto window que tiene un montón de información de la página web donde lo hayamos lanzado
This in web example

Bien ahora ya sabemos un poco que pasa con this en el contexto global y dentro de un método o función, pero ¿que pasaría si nuestra función getInfo fuera un callback de otra, es decir que realmente la hemos pasamos por parámetro? Hagamos la prueba con setTimeout, que como sabemos ejecuta lo que le pasemos por parámetro en el tiempo que le indiquemos, debajo de lo que ya teníamos añadimos

setTimeout(this.superhero.getInfo,500);

Y ejecutamos(ya sabéis con node nombreFichero.js)
Bind this error
Vaya!! no es no lo que esperabamos, ¿verdad?....y esto ¿por qué?.....bueno pensemos lo siguiente el this dentro de una función representa al contexto que lo ha llamado, en nuestro caso this tendría la información del contexto de setTimeout, para que lo veáis un poco más claro cambiar el código dentro de la función por lo siguiente:

var superhero = {}
this.superhero = {
  name: 'Jonathan Osterman',
  alias: 'Dr. Manhattan',
  getInfo: function () {
     
     console.log(this)
     //console.log(this.name + ' se convirtió en el ' + this.alias)
   }

}
console.log(this)

setTimeout(this.superhero.getInfo, 500)

Si os fijáis he comentado nuestra linea con this.name y this.alias y he puesto solo un log con this, el resultado que deberíais ver sería similar a este
Set Timeout this example
Como veis nuestro this es muy distinto de lo que esperabamos, tiene información solo relativa a nuestro setTimeout. Y, ¿cómo lo solucionamos? Es relativamente sencillo, lo que tenemos que hacer es "enlazar" el this que nosotros queramos y eso lo hacemos usando la propiedad bind y le pasamos nuestro propio this.

setTimeout(this.superhero.getInfo.bind(this), 500)

Si ejecutamos ahora lo que teníamos
Bind example
Vemos como el this es el mismo dentro y fuera de setTimeout, ahora solo tenemos que eliminar el log del this dentro de la función, descomentar la línea y.......si nos falta otra cosa como tal hemos enlazado nuestro this, pero esto realmente es el objeto completo para que realmente nos funcione como antes debemos pasarle el objeto superhero

setTimeout(this.superhero.getInfo.bind(this.superhero), 500)

Y ahora sí tenemos nuestra función devolviendo lo que esperábamos dentro de setTimeout
Espero que esto quede más o menos claro, así me lo explicaron a mí los magos de KeepCoding y creo que es la mejor manera.

Lo último que veremos en este post serán las funciones constructoras(que también usan this ;) )
Como ya hemos visto varias cosas pongo un código un pelín más largo, con una función constructora y dos instancias de ésta, con sus dos setTimeout

function superhero() {
  this.name;
  this.alias;
  this.getInfo = function () {
     console.log(this.name + ' se convirtió en ' + this.alias);
   }
}

var mr_manhattan = new superhero();
mr_manhattan.name = 'Jon Osterman';
mr_manhattan.alias = 'Dr. Manhattan';

mr_manhattan.getInfo();

var loki = new superhero();
loki.name = 'Loki Laufeyson';
loki.alias = 'Loki'

loki.getInfo();
setTimeout(mr_manhattan.getInfo, 500);
setTimeout(loki.getInfo, 500);

Bueno más o menos os imaginareis como es una función constructora no? Una función que con ayuda del this representa cada propiedad del objeto instanciado y la mantiene solo en ese objeto.
Si ejecutamos esto tenemos lo siguiente
Constructor example
Como vemos tenemos el mismo problema que antes, asi que vamos a usar nuestro conocido bind pasándole a cada uno su objeto pertinente

setTimeout(mr_manhattan.getInfo.bind(mr_manhattan), 500);
setTimeout(loki.getInfo.bind(loki), 500);

Y vemos como el resultado ya es el que nos interesa
Bind costructor example
Bien con esto aparte de repasar un poco una función constructora rápidamente quería que vierais que el concepto del bind es el mismo para la mayoría de las situaciones en la que nos encontremos. Recordad si tenéis undefinided en algún método pensar en BIND.

Sin mucho más nos vemos en el siguiente. Ciaaooooo