Funciones de flecha y esto [duplicado]

Resuelto thank_you asked hace 9 años • 5 respuestas

Estoy probando ES6 y quiero incluir una propiedad dentro de mi función como esta

var person = {
  name: "jason",

  shout: () => console.log("my name is ", this.name)
}

person.shout() // Should print out my name is jason

Sin embargo, cuando ejecuto este código, la consola solo registra my name is. ¿Qué estoy haciendo mal?

thank_you avatar Mar 02 '15 02:03 thank_you
Aceptado

Respuesta corta: thisapunta al límite más cercano this; el código proporcionado thisse encuentra en el alcance adjunto.

Respuesta más larga: las funciones de flecha no tienen ningún nombrethis especial u argumentsotros nombres especiales vinculados ; cuando se crea el objeto, el nombre thisse encuentra en el ámbito adjunto, no en el personobjeto. Puedes ver esto más claramente moviendo la declaración:

var person = {
  name: "Jason"
};
person.shout = () => console.log("Hi, my name is", this);

Y aún más claro cuando se traduce en una vaga aproximación de la sintaxis de las flechas en ES5:

var person = {
  name: "Jason"
};
var shout = function() {
  console.log("Hi, my name is", this.name);
}.bind(this);
person.shout = shout;

En ambos casos, this(para la función de grito) apunta al mismo alcance persondefinido en, no al nuevo alcance al que se adjunta la función cuando se agrega al personobjeto.

No puedes hacer que las funciones de flecha funcionen de esa manera, pero, como @kamituel señala en su respuesta , puedes aprovechar el patrón de declaración de método más corto en ES6 para obtener ahorros de espacio similares:

var person = {
  name: "Jason",
  // ES6 "method" declaration - leave off the ":" and the "function"
  shout() {
    console.log("Hi, my name is", this.name);
  }
};
Sean Vieira avatar Mar 01 '2015 19:03 Sean Vieira

De acuerdo con @Sean Vieira: en este caso thisestá vinculado al objeto global (o, como se señala en el comentario, de manera más general a un alcance adjunto).

Si desea tener una sintaxis más corta, existe otra opción: los literales de objetos mejorados admiten sintaxis corta para funciones de propiedad. thisestará atado como espera allí. Ver shout3():

window.name = "global";

var person = {
    name: "jason",

    shout: function () {
        console.log("my name is ", this.name);
    },
    shout2: () => {
        console.log("my name is ", this.name);
    },
    // Shorter syntax
    shout3() {
        console.log("my name is ", this.name);
    }
};

person.shout();  // "jason"
person.shout2(); // "global"
person.shout3(); // "jason"
kamituel avatar Mar 01 '2015 20:03 kamituel