Como notei que não explicaram a diferença entre () => {} para function() {}, então apesar de haver uma resposta marcada como correta, vou explicar está diferença.
Primeiramente é muito comum achar que ambos os códigos são equivalentes, já que o ES6 trouxe diversos syntax sugar para deixar o código mais legível e conciso, as arrow functions são normalmente confundidas com as functions do ES5. Mas indo direto ao ponto existem cinco diferenças entre ambos os códigos:
Contexto Arrow functions possuem this léxico enquanto o modelo normal possui this dinâmico. Isso significa que arrow functions herdam o contexto local de onde foi declarado, enquanto o modelo normal possui o contexto associado ao objeto que ele está vinculado no momento da chamada (se ele não estiver associado a ninguém na chamada, ele assumirá this automaticamente como o contexto global, que no caso dos navegadores é window)
var normal = function() { return this === obj; };
var arrow = () => { return this === window; };
var obj = { normal: normal, arrow: arrow };
obj.normal(); // true obj.arrow(); // true
normal(); // false Constructor Arrow functions não podem ser constructors, então não é possível usar o operador new com a mesma.
var Normal = function() {}; var Arrow = () => {};
new Normal(); // Normal {} new Arrow(); // Arrow is not a constructor Arguments Arrow functions não possui o objeto array-like arguments.
var noop = () => { return arguments; }
noop(); // ReferenceError: arguments is not defined Nome de função Expressões de função podem ser nomeadas explicatamente, isso é útil em alguns cenários que envolvem recursão e para em casos de exceção fica mais fácil de rastrear o código, visto que o nome da função é usado na pilha de exceção mostrada ao desenvolvedor. Só que Arrows Functions não podem ser nomeadas explicitamente, elas acabam herdando o nome da variável onde foi criada.
var fn = function nome() {}; fn.name; // nome
var fn = () => {}; fn.name; // fn Retorno Expressões de função precisam declarar explicitamente qual será o retorno da função, enquanto Arrow Functions permitem escrever em um modelo encurtado onde a última expressão analisada será o retorno da função quando é omitido as chaves {}.
var fn = function() { return 1; }; // retorna 1
var fn = () => 1; // retorna 1 var fn = () => (1, 2, 3); // retorna 3, última expressão avaliada
var fn = () => { 1 }; // retorna undefined var fn = () => { return 1 }; // retorna 1 O que seria um modelo equivalente de () => {} então? Ignorando o caso de que arrow functions não podem ser usadas como constructors e não recebem arguments, o modelo mais equivalente entre arrow functions e funções tradicionais seria este:
// modelo nomeado var name = (() => { /* code / }) var name = (function name() { / code */ }).bind(this)
// modelo anônimo (() => { /* code / }) (function() { / code */ }).bind(this) Neste caso o code pode ser exatamente o mesmo entre os dois modelos e eles irão funcionar exatamente igual. Mas claro, existem outras maneiras de simular o comportamento das arrow functions. Um deles é armazenar o contexto this em uma variável e usar essa variável na função tradicional em vez do seu próprio this, o que as outras respostas mostraram.