javascript this ecmascript-6 arrow-functions

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í:

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 this cuando se crean no tiene 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); } };