Arrow Functions — Declaração, funcionamento, escopos e o valor de this

Raphael Lima
4 min readApr 17, 2017

--

O que são e como funcionam as Arrow Functions?

A nova versão do JavaScript, a ES6, trouxe novas features e dentre elas uma nova forma de criar funções usando o operador =>. Esta nova forma de se trabalhar com funções são chamadas Arrow Functions.

Vejamos um exemplo de como declarar arrow functions:

const sum = (num1, num2) => {
return num1 + num2;
}
console.log(sum(1, 2));

Podemos encurtar ainda mais a sintaxe de uma arrow function, desde que ela possua apenas uma declaração:

const sum = (num1, num2) => num1 + num2;

Ou seja, uma expressão arrow function possui uma sintaxe mais curta, semelhante as expressões lambda presente em linguagens como Java, F# entre outras.
As arrow functions possuem dois benefícios:

  • São menos verbosas do que as funções tradicionais
  • Seu valor de this é definido à partir das funções onde foram definidas. Ou seja, não é mais necessário fazer bind() ou armazenar o estado em that = this;

Vejamos um exemplo:

function Exemplo(parametro) {
this.parametro = parametro;
}
Exemplo.prototype.exemploArray = function (vetor) {
'use strict';
return vetor.map(function (elemento) {
return this.parametro + elemento;
});
};

Quando tentamos acessar o this.parametro nosso código não funciona, por que o this está associado a função passada como argumento para a função map.
Existe algumas possibilidades de resolvermos o problema do this nessas ocasiões.

1° — const that = this

A solução de armazenar o valor de this em uma variável é uma das mais comuns no desenvolvimento de aplicações JavaScript, ou seja, armazenamos o valor de this e o acessamos de outras funções. Vejamos um exemplo:

function Exemplo(param) {
this.param = param;
}
Exemplo.prototype.exemploArray = function (vetor) {
var that = this; // Este é o ponto!
return vetor.map(function (elem) {
return that.param + elem;
});
};

Como a variável that pode ser acessada à partir de outras funções, conseguimos acessar o valor de this do prototype de Exemplo.

2º — Especificando o valor de this

Alguns métodos de Array tem um parâmetro extra para justamente especificarmos o valor que o this deve ter quando a função de callback é executada conforme podemos ver no código abaixo:

function Exemplo(param) {
this.param = param;
}
Exemplo.prototype.exemploArray = function (vetor) {
return vetor.map(function (elem) {
return that.param + elem;
}, this); // --> Segundo parâmetro (this) passado como argumento para a função map.
};

3º — Fazendo bind(this)

Podemos usar o método bind() para passarmos o valor de this para o objeto passado como argumento. Vejamos um exemplo:

function Exemplo(param) {
this.param = param;
}
Exemplo.prototype.exemploArray = function (vetor) {
return vetor.map(function (elem) {
return that.param + elem;
}.bind(this)); // --> função bind(this) feita na função map.
};

4° — Arrow Functions

O funcionamento da arrow function funciona de forma semelhante ao item 3. Embora tenha sido passado uma função (arrow) para o método map, o valor de this, com a arrow function, é o da função exemploArray().

function Exemplo(param) {
this.param = param;
}
Exemplo.prototype.exemploArray = function (vetor) {
return vetor.map( elem => this.param + elem )
};

Escopo de uma Arrow Function e o valor de ‘this’

Antes das arrow functions todas as funções definiam seu próprio valor de this. O valor de this em uma arrow function é o mesmo valor do this do escopo encapsulado ao invés de referenciar o contexto do objeto, ou seja, o objeto dentro do qual foi definida. Com isso, o escopo de uma arrow function pode ser tanto o escopo de uma função ou o escopo global, dentro de quaisquer que seja onde a arrow function foi declarada.
Vejamos um exemplo para entendermos a diferença entre o valor de this nas funções “tradicionais” e arrow functions:

// Rode esses exemplos no browser
let example = {
f1: function() {
console.log(this);
let f2 = function() {
console.log(this);
}
f2();
}
}
example.f1();

A saída será: Object, Window e Window;

Aqui, o valor de this dentro da função f1() refere ao objeto example, pois f1 é uma propriedade de example. O this dentro da função f2() referencia ao objeto window devido f2 ser uma propriedade do objeto window. Vejamos agora, alterando o código para arrow function para vermos o comportamento de this:

let example = {
f1: () => {
console.log(this);
let f2 = () => console.log(this);
f2();
}
}
example.f1();

A saída será: Window, Window e Window;

Aqui, o valor de this dentro da função f1() referencia o valor de this do escopo global. O this dentro da função f2 referencia o valor de this da função f1() devido a função f2 ser uma propriedade de f1 e estar em seu escopo.

Considerações finais

As arrow functions não podem ser usadas como construtores, pois não podemos aplicar o operador new a elas. Com excessão a sintaxe, valor de this e o operador new, tudo mais continua funcionando da mesma forma em ambas declarações, seja arrow function, seja funções tradicionais, ou seja, ambos são instâncias de Function.

--

--