javascript - Funciones de flecha y esto
this ecmascript-6 (5)
Aquí el valor de esto dentro de la función está determinado por el lugar donde se define la función de flecha, no donde se utiliza.
Entonces
this
refiere al objeto global / ventana si no está envuelto en otro espacio de nombres
Esta pregunta ya tiene una respuesta aquí:
- Métodos en objetos ES6: uso de funciones de flecha 3 respuestas
Estoy probando ES6 y quiero incluir una propiedad dentro de mi función así
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 esta consola de código solo registra
my name is
.
¿Qué estoy haciendo mal?
De acuerdo con @Sean Vieira: en este caso,
this
está vinculado al objeto global (o, como se señala en el comentario, más generalmente a un alcance de cierre).
Si desea tener una sintaxis más corta, hay otra opción: los literales de objetos mejorados admiten sintaxis corta para funciones de propiedad.
this
estará obligado como esperas 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"
El problema es que ( MDN )
Una expresión de función de flecha [...] enlaza léxicamente este valor.
Las funciones de flecha capturan este valor del contexto envolvente.
Por lo tanto, el valor de
this
en esa función será el valor de
this
donde cree el objeto literal.
Probablemente, será una
window
en modo no estricto e
undefined
en modo estricto.
Para solucionarlo, debe usar una función normal:
var person = {
name: "jason",
shout: function(){ console.log("my name is ", this.name) }
}
person.shout();
La respuesta aceptada es excelente, concisa y clara, pero elaboraré un poco sobre lo que dijo Sean Vieira:
Las funciones de flecha no tienen estos argumentos u otros nombres especiales vinculados en absoluto.
Debido a que la función de flecha no tiene un "this", utiliza el "this" del padre. "this" siempre apunta al padre, y el padre del objeto persona es Window (si está en un navegador).
Para probarlo, ejecuta esto en tu consola:
var person = {
name: "Jason",
anotherKey: this
}
console.log(person.anotherKey)
Obtendrás el objeto Window.
Considero que esta es una forma realmente útil de pensarlo. No es toda la historia, ya que el "esto" de un objeto literal es otra discusión.
Respuesta corta:
this
apunta al límite más cercano: en el código, siempre que se encuentre en el alcance adjunto.
Respuesta más larga: funciones de flecha
atar su
no tiene
this
cuando se crean
this
,
arguments
u otros nombres especiales vinculados
en absoluto
: cuando se crea el objeto, el nombre se encuentra en el alcance adjunto, no el objeto de
person
.
Puede 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 aproximación vaga de la sintaxis de flecha 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 ámbito en el
person
se define la
person
, no al nuevo ámbito al que se adjunta la función cuando se agrega al objeto de
person
.
No puede hacer que las funciones de flecha funcionen de esa manera, pero, como señala @kamituel en su respuesta , puede 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);
}
};