Funciones de flecha y esto [duplicado]
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?
Respuesta corta: this
apunta al límite más cercano this
; el código proporcionado this
se encuentra en el alcance adjunto.
Respuesta más larga: las funciones de flecha
no tienen ningún nombrethis
especial u arguments
otros nombres especiales vinculados ; cuando se crea el objeto, el nombre this
se encuentra en el ámbito adjunto, no en el person
objeto. 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 person
definido en, no al nuevo alcance al que se adjunta la función cuando se agrega al person
objeto.
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);
}
};
De acuerdo con @Sean Vieira: en este caso this
está 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. this
estará 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"