Fundamentos de jQuery

2.12. La palabra clave this

En JavaScript, así como en la mayoría de los lenguajes de programación orientados a objetos, this es una palabra clave especial que hace referencia al objeto en donde el método está siendo invocado. El valor de this es determinado utilizando una serie de simples pasos:

  1. Si la función es invocada utilizando Function.call o Function.apply, this tendrá el valor del primer argumento pasado al método. Si el argumento es nulo (null) o indefinido (undefined), this hará referencia el objeto global (el objeto window);
  2. Si la función a invocar es creada utilizando Function.bind, this será el primer argumento que es pasado a la función en el momento en que se la crea;
  3. Si la función es invocada como un método de un objeto, this referenciará a dicho objeto;
  4. De lo contrario, si la función es invocada como una función independiente, no unida a algún objeto, this referenciará al objeto global.

Una función invocada utilizando Function.call

var myObject = {
    sayHello : function() {
        console.log('Hola, mi nombre es ' + this.myName);
    },
    myName : 'Rebecca'
};

var secondObject = {
    myName : 'Colin'
};

myObject.sayHello();                  // registra 'Hola, mi nombre es Rebecca'
myObject.sayHello.call(secondObject); // registra 'Hola, mi nombre es Colin'

Una función creada utilizando Function.bind

var myName = 'el objeto global',

    sayHello = function () {
        console.log('Hola, mi nombre es ' + this.myName);
    },
    myObject = {
        myName : 'Rebecca'
    };

var myObjectHello = sayHello.bind(myObject);

sayHello();       // registra 'Hola, mi nombre es el objeto global'
myObjectHello();  // registra 'Hola, mi nombre es Rebecca'

Una función vinculada a un objeto

var myName = 'el objeto global',
    sayHello = function() {
        console.log('Hola, mi nombre es ' + this.myName);
    },
    myObject = {
        myName : 'Rebecca'
    },
    secondObject = {
        myName : 'Colin'
    };

myObject.sayHello = sayHello;
secondObject.sayHello = sayHello;

sayHello();               // registra 'Hola, mi nombre es el objeto global'
myObject.sayHello();      // registra 'Hola, mi nombre es Rebecca'
secondObject.sayHello();  // registra 'Hola, mi nombre es Colin'

En algunas oportunidades, cuando se invoca una función que se encuentra dentro de un espacio de nombres (en inglés namespace) amplio, puede ser una tentación guardar la referencia a la función actual en una variable más corta y accesible. Sin embargo, es importante no realizarlo en instancias de métodos, ya que puede llevar a la ejecución de código incorrecto. Por ejemplo:

var myNamespace = {
    myObject : {
        sayHello : function() {
            console.log('Hola, mi nombre es ' + this.myName);
        },
        myName : 'Rebecca'
    }
};

var hello = myNamespace.myObject.sayHello;
hello();  // registra 'Hola, mi nombre es undefined'

Para que no ocurran estos errores, es necesario hacer referencia al objeto en donde el método es invocado:

var myNamespace = {
    myObject : {
        sayHello : function() {
            console.log('Hola, mi nombre es ' + this.myName);
        },
        myName : 'Rebecca'
    }
};

var obj = myNamespace.myObject;
obj.sayHello();  // registra 'Hola, mi nombre es Rebecca'