Insatisfeito com as outras respostas. A resposta mais votada em 2019/3/13 está realmente errada.
A versão resumida curta do que =>
significa é que é um atalho para escrever uma função E para vinculá-la à atualthis
const foo = a => a * 2;
É efetivamente um atalho para
const foo = function(a) { return a * 2; }.bind(this);
Você pode ver todas as coisas que foram encurtadas. Não precisávamos function
, nem return
nem .bind(this)
nem chaves nem parênteses
Um exemplo um pouco mais longo de uma função de seta pode ser
const foo = (width, height) => {
const area = width * height;
return area;
};
Mostrando que, se queremos múltiplos argumentos para a função, precisamos de parênteses e se queremos escrever mais do que uma única expressão, precisamos de chaves e um explícito return
.
É importante entender a .bind
parte e é um grande tópico. Tem a ver com o que this
significa em JavaScript.
Todas as funções têm um parâmetro implícito chamado this
. Como this
é definido ao chamar uma função depende de como essa função é chamada.
Toma
function foo() { console.log(this); }
Se você chamar normalmente
function foo() { console.log(this); }
foo();
this
será o objeto global.
Se você estiver no modo estrito
`use strict`;
function foo() { console.log(this); }
foo();
// or
function foo() {
`use strict`;
console.log(this);
}
foo();
Será undefined
Você pode definir this
diretamente usando call
ouapply
function foo(msg) { console.log(msg, this); }
const obj1 = {abc: 123}
const obj2 = {def: 456}
foo.call(obj1, 'hello'); // prints Hello {abc: 123}
foo.apply(obj2, ['hi']); // prints Hi {def: 456}
Você também pode definir this
implicitamente usando o operador de ponto.
function foo(msg) { console.log(msg, this); }
const obj = {
abc: 123,
bar: foo,
}
obj.bar('Hola'); // prints Hola {abc:123, bar: f}
Um problema surge quando você deseja usar uma função como retorno de chamada ou ouvinte. Você cria a classe e deseja atribuir uma função como retorno de chamada que acessa uma instância da classe.
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click', function() {
console.log(this.name); // won't work
});
}
}
O código acima não funcionará porque quando o elemento acionar o evento e chamar a função, o this
valor não será a instância da classe.
Uma maneira comum de resolver esse problema é usar .bind
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click', function() {
console.log(this.name);
}.bind(this); // <=========== ADDED! ===========
}
}
Como a sintaxe da seta faz a mesma coisa que podemos escrever
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click',() => {
console.log(this.name);
});
}
}
bind
efetivamente cria uma nova função . Se bind
não existisse, você poderia basicamente fazer o seu próprio como este
function bind(funcitonToBind, valueToUseForThis) {
return function(...args) {
functionToBind.call(valueToUseForThis, ...args);
};
}
No JavaScript antigo, sem o operador de propagação, seria
function bind(funcitonToBind, valueToUseForThis) {
return function() {
functionToBind.apply(valueToUseForThis, arguments);
};
}
A compreensão desse código requer um entendimento dos fechamentos, mas a versão curta bind
cria uma nova função que sempre chama a função original com o this
valor que estava vinculado a ela. A função de seta faz a mesma coisa, pois é um atalho parabind(this)