Lær ES6 Dope Way del II: Pilfunktioner og 'dette' nøgleord

Velkommen til del II af Lær ES6 The Dope Way, en serie oprettet for at hjælpe dig med let at forstå ES6 (ECMAScript 6)!

Så hvad dælen er => ; ?

Du har sandsynligvis set disse mærkelige egyptiske hieroglyffer-symboler her og der, især i en andens kode, hvor du i øjeblikket debugger et ' dette' nøgleordsproblem. Efter en times tinkering strejfer du nu på Google-søgefeltet og forfølger Stack Overflow. Lyder det velkendt?

Lad os sammen dække tre emner i Lær ES6 Dope Way del II:

  • Hvordan ' dette ' nøgleord vedrører => .
  • Sådan overføres funktioner fra ES5 til ES6.
  • Vigtige egenskaber at være opmærksom på, når du bruger => .

Pilfunktioner

Pilfunktioner blev oprettet for at forenkle funktionsomfanget og gøre brugen af ​​' dette ' nøgleord meget mere ligetil. De bruger = & gt; syntaks, der ligner en pil. Selvom jeg ikke tror, ​​at det er nødvendigt at gå på diæt, kalder folk det for "det fede arrow" (og Ruby-entusiaster ved det måske bedre som "hash rock et") - noget at være opmærksom på.

Hvordan 'dette' nøgleord vedrører pilefunktioner

Før vi dykker dybere ned i ES6-pilfunktioner, er det vigtigt først at have et klart billede af, hvad ' dette ' binder til i ES5-koden.

Hvis " dette " nøgleord var inde i et objekts metode (en funktion, der tilhører et objekt), hvad ville det så henvise til?

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

Korrekt! Det refererer til objektet. Vi kommer til hvorfor senere.

Hvad nu hvis ' dette ' nøgleord var inden for metodens funktion?

// 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. 

Hvad fik du? Vent, hvad skete der med vores kanin ...?

Ah, troede du, at ' dette ' refererer til metodens indre funktion?

Måske selve objektet?

Du er klog at tro det, men alligevel er det ikke sådan. Tillad mig at lære dig, hvad de kodende ældste engang havde lært mig:

Coding Ældste :Åh ja, t han kode er stærk med denne ene. Det er faktisk praktisk at tænke, at 'dette' nøgleord binder til funktionen, men sandheden er, at 'dette' nu er faldet uden for anvendelsesområdet ... Det tilhører nu ... ", han holder pause som om han oplever indre uro ," vindueobjektet .

Det er rigtigt. Sådan skete det.

Hvorfor binder ' dette ' til vindueobjektet? Fordi ' dette ' altid refererer til ejeren af ​​den funktion, den er i, for dette tilfælde - da det nu er uden for rækkevidde - vinduet / det globale objekt.

Når det er inde i et objekts metode - funktionens ejer er objektet. Således er dette 'nøgleord bundet til objektet. Men når det er inde i en funktion, enten stå alene eller inden for en anden metode, vil det altid henvise til vinduet / det globale objekt.

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

Men hvorfor…?

Dette er kendt som en JavaScript-quirk, hvilket betyder noget, der bare sker inden for JavaScript, der ikke ligefrem er ligetil, og det fungerer ikke som du ville tro. Dette blev også betragtet af udviklere som et dårligt designvalg, som de nu afhjælper med ES6s pilfunktioner.

Før vi fortsætter, er det vigtigt at være opmærksom på to smarte måder, som programmører løser ' dette ' problem inden for ES5-koden, især da du fortsætter med at løbe ind i ES5 et stykke tid (ikke alle browsere er migreret fuldt ud til ES6 endnu):

# 1 Opret en variabel uden for metodens indre funktion. Nu får metoden 'forEach' adgang til ' dette ' og dermed objektets egenskaber og deres værdier. Dette skyldes, at ' dette ' lagres i en variabel, mens det stadig er inden for omfanget af objektets direkte metode '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 Brug bind for at vedhæfte ' dette ' nøgleord, der henviser til metoden, til metodens indre funktion.

// 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

Og nu introducerer ... Pilfunktioner! At håndtere ' dette ' problem har aldrig været lettere og mere ligetil! Den enkle ES6-løsning:

// 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

Mens i ES5 ' dette ' henviste til funktionens overordnede, i ES6 bruger pilfunktioner leksikalskopning - ' dette ' refererer til det nuværende omgivende omfang og ikke længere. Således vidste den indre funktion kun at binde sig til den indre funktion og ikke til objektets metode eller selve objektet.

Sådan overføres funktioner fra ES5 til 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");

Du gjorde det! Godt arbejde! Enkelt nok, ikke? Her er et par flere eksempler, der bruger den tynde tynde pil for at vænne dine øjne:

// #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(); });

Vigtige egenskaber at være opmærksom på, når du bruger pilefunktioner

Hvis du bruger det 'nye' nøgleord med => funktioner, vil det kaste en fejl. Pilfunktioner kan ikke bruges som konstruktør - normale funktioner understøtter det 'nye' via egenskabsprototypen og den interne metode [[Konstruer]]. Pilfunktioner bruger ikke hverken, så den nye (() => {}) kaster en fejl.

Yderligere spørgsmål at overveje:

// 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. }

Tillykke! Du har gjort det gennem Learn ES6 The Dope Way Part II, og nu har du et grundlag for viden om pilfunktion, de leksikale fordele, det giver til ' dette ', og fik også dig selv nogle JavaScript quirk færdigheder! :)

Hold din visdom opdateret ved at like og følge som mere Lær ES6 Dope Way kommer snart til Medium!

Del I: const, let & var

Del II: (Pil) => funktioner og 'dette' nøgleord

Del III: Skabelonlitteratur, Spread Operators & Generators!

Del IV: Standardparametre, destruktionstildeling og en ny ES6-metode!

Del V: Klasser, transponering af ES6-kode og flere ressourcer!

Du kan også finde mig på github ❤ //github.com/Mashadim