Aprenda ES6 The Dope Way Parte II: Funções de seta e a palavra-chave 'this'

Bem-vindo à Parte II do Learn ES6 The Dope Way, uma série criada para ajudá-lo a compreender facilmente o ES6 (ECMAScript 6)!

Então, o que diabos é => ; ?

Você provavelmente já viu esses símbolos hieróglifos de aparência egípcia estranhos aqui e ali, especialmente no código de outra pessoa, onde atualmente está depurando um problema de palavra-chave 'esta' . Depois de uma hora de ajustes, você agora está vagando pela barra de pesquisa do Google e perseguindo Stack Overflow. Soa familiar?

Juntos, vamos cobrir três tópicos em Aprenda ES6 The Dope Way Parte II:

  • Como a palavra-chave ' this ' está relacionada a => .
  • Como migrar funções de ES5 para ES6.
  • Quinquilharias importantes a serem observadas ao usar => .

Funções de seta

As funções de seta foram criadas para simplificar o escopo da função e tornar o uso da palavra-chave ' this ' muito mais direto. Eles utilizam o = & gt; sintaxe, que se parece com uma seta. Mesmo que eu não ache que ele precise fazer dieta, as pessoas o chamam de “a gordura arrow ” (e os entusiastas do Ruby podem conhecê-lo melhor como “hash rock et”) - algo a ter em conta.

Como a palavra-chave 'this' se relaciona com as funções das setas

Antes de nos aprofundarmos nas funções de seta do ES6, é importante primeiro ter uma imagem clara do que " isso " está vinculado ao código ES5.

Se a palavra-chave ' this ' estivesse dentro do método de um objeto (uma função que pertence a um objeto), a que se referia?

// Test it here: //jsfiddle.net/maasha/x7wz1686/ var bunny = { name: 'Usagi', showName: function() { alert(this.name); } }; bunny.showName(); // Usagi

Corrigir! Isso se referiria ao objeto. Veremos o porquê mais tarde.

Agora, e se a palavra-chave ' this ' estivesse dentro da função do método?

// Test it here: //jsfiddle.net/maasha/z65c1znn/ var bunny = { name: 'Usagi', tasks: ['transform', 'eat cake', 'blow kisses'], showTasks: function() { this.tasks.forEach(function(task) { alert(this.name + " wants to " + task); }); } }; bunny.showTasks(); // [object Window] wants to transform // [object Window] wants to eat cake // [object Window] wants to blow kisses // please note, in jsfiddle the [object Window] is named 'result' within inner functions of methods. 

O que você conseguiu? Espere, o que aconteceu com nosso coelho ...?

Ah, você acha que ' isso ' se refere à função interna do método?

Talvez o próprio objeto?

Você é sábio em pensar assim, mas não é assim. Permita-me ensinar o que os codificadores mais velhos me ensinaram:

Codificação Elder :Ah sim, t ele código é forte com este. Na verdade, é prático pensar que a palavra-chave 'this' se liga à função, mas a verdade é que 'isso' agora está fora do escopo ... Agora pertence a ... ”, ele faz uma pausa como se estivesse experimentando uma turbulência interna ,“ o objeto janela .

Está certo. Foi exatamente assim que aconteceu.

Por que ' this ' se liga ao objeto da janela? Porque ' this ', sempre faz referência ao proprietário da função em que está, neste caso - uma vez que agora está fora do escopo - a janela / objeto global.

Quando está dentro do método de um objeto - o dono da função é o objeto. Portanto, a palavra-chave ' this ' está vinculada ao objeto. Porém, quando está dentro de uma função, independente ou dentro de outro método, sempre fará referência à janela / objeto global.

// Test it here: //jsfiddle.net/maasha/g278gjtn/ var standAloneFunc = function(){ alert(this); } standAloneFunc(); // [object Window]

Mas por que…?

Isso é conhecido como uma peculiaridade do JavaScript, que significa algo que simplesmente acontece dentro do JavaScript que não é exatamente simples e não funciona da maneira que você imagina. Isso também foi considerado pelos desenvolvedores como uma escolha de design ruim, que eles agora estão corrigindo com as funções de seta do ES6.

Antes de continuarmos, é importante estar ciente de duas maneiras inteligentes como os programadores resolvem o problema ' este ' dentro do código ES5, especialmente porque você continuará executando o ES5 por um tempo (nem todo navegador migrou totalmente para o ES6 ainda):

# 1 Crie uma variável fora da função interna do método. Agora, o método 'forEach' obtém acesso a ' this ' e, portanto, às propriedades do objeto e seus valores. Isso ocorre porque ' this ' está sendo armazenado em uma variável enquanto ainda está dentro do escopo do método direto do objeto 'showTasks'.

// Test it here: //jsfiddle.net/maasha/3mu5r6vg/ var bunny = { name: 'Usagi', tasks: ['transform', 'eat cake', 'blow kisses'], showTasks: function() { var _this = this; this.tasks.forEach(function(task) { alert(_this.name + " wants to " + task); }); } }; bunny.showTasks(); // Usagi wants to transform // Usagi wants to eat cake // Usagi wants to blow kisses

# 2 Use bind para anexar a palavra-chave ' this ' que se refere ao método à função interna do método.

// Test it here: //jsfiddle.net/maasha/u8ybgwd5/ var bunny = { name: 'Usagi', tasks: ['transform', 'eat cake', 'blow kisses'], showTasks: function() { this.tasks.forEach(function(task) { alert(this.name + " wants to " + task); }.bind(this)); } }; bunny.showTasks(); // Usagi wants to transform // Usagi wants to eat cake // Usagi wants to blow kisses

E agora apresentando… funções de seta! Lidar com ' este ' problema nunca foi tão fácil e simples! A solução ES6 simples:

// Test it here: //jsfiddle.net/maasha/che8m4c1/ var bunny = { name: 'Usagi', tasks: ['transform', 'eat cake', 'blow kisses'], showTasks() { this.tasks.forEach((task) => { alert(this.name + " wants to " + task); }); } }; bunny.showTasks(); // Usagi wants to transform // Usagi wants to eat cake // Usagi wants to blow kisses

Enquanto no ES5 ' isto ' se refere ao pai da função, no ES6, as funções de seta usam escopo léxico - ' isto ' se refere ao escopo circundante atual e não mais. Assim, a função interna sabia se ligar apenas à função interna, e não ao método do objeto ou ao próprio objeto.

Como migrar funções de ES5 para ES6.

// Before let bunny = function(name) { console.log("Usagi"); } // After let bunny = (name) => console.log("Usagi") // Step 1: Remove the word ‘function’. let bunny = (name) { console.log("Usagi"); } // Step 2: If your code is less than a line, remove brackets and place on one line. let bunny = (name) console.log("Usagi"); // Step 3. Add the hash rocket. let bunny = (name) => console.log("Usagi");

Você fez isso! Bom trabalho! Simples, certo? Aqui estão mais alguns exemplos utilizando a flecha mais gorda e fina, para acostumar seus olhos:

// #1 ES6: if passing one argument you don't need to include parenthesis around parameter. var kitty = name => name; // same as ES5: var kitty = function(name) { return name; }; // #2 ES6: no parameters example. var add = () => 3 + 2; // same as ES5: var add = function() { return 3 + 2; }; // #3 ES6: if function consists of more than one line or is an object, include braces. var objLiteral = age => ({ name: "Usagi", age: age }); // same as ES5: var objLiteral = function(age) { return { name: "Usagi", age: age }; }; // #4 ES6: promises and callbacks. asyncfn1().then(() => asyncfn2()).then(() => asyncfn3()).then(() => done()); // same as ES5: asyncfn1().then(function() { asyncfn2(); }).then(function() { asyncfn3(); }).done(function() { done(); });

Quildades importantes a serem observadas ao usar funções de seta

Se você usar a palavra-chave 'new' com => funções, ocorrerá um erro. As funções de seta não podem ser usadas como construtor - as funções normais suportam o 'novo' por meio do protótipo de propriedade e método interno [[Construct]]. As funções de seta não usam nenhum dos dois, portanto, o novo (() => {}) gera um erro.

Outras peculiaridades a serem consideradas:

// Line breaks are not allowed and will throw a syntax error let func1 = (x, y) => { return x + y; }; // SyntaxError // But line breaks inside of a parameter definition is ok let func6 = ( x, y ) => { return x + y; }; // Works! // If an expression is the body of an arrow function, you don’t need braces: asyncFunc.then(x => console.log(x)); // However, statements have to be put in braces: asyncFunc.catch(x => { throw x }); // Arrow functions are always anonymous which means you can’t just declare them as in ES5: function squirrelLife() { // play with squirrels, burrow for food, etc. } // Must be inside of a variable or object property to work properly: let squirrelLife = () => { // play with squirrels, burrow for food, etc. // another super squirrel action. }

Parabéns! Você passou por Aprenda ES6 The Dope Way Parte II e agora você tem uma base para o conhecimento da função da flecha, os benefícios lexicais que isso dá a ' isso ' e também conseguiu algumas habilidades peculiares do JavaScript! :)

Mantenha sua sabedoria atualizada curtindo e seguindo conforme mais Aprenda ES6 The Dope Way estará disponível em breve no Medium!

Parte I: const, let & var

Parte II: (Seta) => funções e palavra-chave 'esta'

Parte III: Literais de modelo, operadores de propagação e geradores!

Parte IV: Parâmetros padrão, atribuição de desestruturação e um novo método ES6!

Parte V: Classes, Transpiling ES6 Code e mais recursos!

Você também pode me encontrar no github ❤ //github.com/Mashadim