Funções de seta e isto

Eu estou tentando ES6 e quero include uma propriedade dentro da minha function como assim

var person = { name: "jason", shout: () => console.log("my name is ", this.name) } person.shout() // Should print out my name is jason 

No entanto, quando eu executo este console de código só registra my name is . O que estou fazendo de errado?

Resposta curta: this aponta para o limite mais próximo this – no código fornecido, this é encontrado no escopo anexo.

Resposta mais longa: funções de seta vincular sua this quando eles são criados não tem this , arguments ou outros nomes especiais ligados – quando o object está sendo criado, o nome é encontrado no escopo incluído, não no object person . Você pode ver isso mais claramente movendo a declaração:

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

E ainda mais claro quando traduzido em uma aproximação vaga da syntax da flecha no ES5:

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

Em ambos os casos, this (para a function shout) aponta para o mesmo escopo em que a person está definida, não o novo escopo ao qual a function é anexada quando é adicionada ao object person .

Você não pode fazer com que as funções de seta funcionem dessa maneira, mas, como aponta @kamituel em sua resposta , você pode tirar proveito do padrão de declaração de método mais curto no ES6 para obter economias de espaço semelhantes:

 var person = { name: "Jason", // ES6 "method" declaration - leave off the ":" and the "function" shout() { console.log("Hi, my name is", this.name); } }; 

Concordou com @Sean Vieira – neste caso, this está ligado ao object global (ou, como apontado no comentário, mais geralmente a um escopo de inclusão).

Se você quiser ter uma syntax mais curta, existe outra opção – literais de object aprimorados suportam syntax curta para funções de propriedade. this será ligado como você espera lá. Veja 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" 

Aqui, o valor deste dentro da function é determinado por onde a function de seta é definida e não onde é usada.

Então, this se refere ao object global / window se não for empacotado em outro namespace

A resposta aceita é excelente, concisa e clara, mas vou elaborar um pouco sobre o que Sean Vieira disse:

As funções de seta não possuem esses argumentos ou outros nomes especiais vinculados.

Como a function de seta não tem um “isso”, ele usa o “this” do pai. “this” sempre aponta para o pai e o pai do object da pessoa é Window (se você estiver em um navegador).

Para provar isso, execute isso no seu console:

 var person = { name: "Jason", anotherKey: this } console.log(person.anotherKey) 

Você obterá o object Window.

Acho isso uma maneira realmente útil de pensar sobre isso. Não é bem a história completa, já que o “isto” de um object literal é outra discussão.

O problema é que ( MDN )

Uma expressão de function de seta […] lexicalmente liga este valor.

As funções de seta capturam o valor desse contexto.

Portanto, o valor this nessa function será o valor this onde você cria o literal do object. Provavelmente, isso será window no modo não-estrito e undefined no modo estrito.

Para consertar isso, você deve usar uma function normal:

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