Lernen Sie ES6 The Dope Way Teil II: Pfeilfunktionen und das Schlüsselwort 'this'

Willkommen zu Teil II von Learn ES6 The Dope Way, einer Reihe, die erstellt wurde, um Ihnen das Verständnis von ES6 (ECMAScript 6) zu erleichtern!

Also, was zum Teufel ist => ; ?

Wahrscheinlich haben Sie diese seltsamen ägyptisch aussehenden Hieroglyphen-Symbole hier und da gesehen, insbesondere im Code eines anderen, in dem Sie derzeit ein " this" -Schlüsselwortproblem debuggen . Nach einer Stunde Basteln durchstreifen Sie jetzt die Google-Suchleiste und verfolgen den Stapelüberlauf. Klingt bekannt?

Lassen Sie uns gemeinsam drei Themen in Learn ES6 The Dope Way Teil II behandeln:

  • Wie sich das Schlüsselwort ' this ' auf => bezieht .
  • So migrieren Sie Funktionen von ES5 nach ES6.
  • Wichtige Macken, die Sie bei der Verwendung von => beachten sollten .

Pfeilfunktionen

Pfeilfunktionen wurden erstellt, um den Funktionsumfang zu vereinfachen und die Verwendung des Schlüsselworts ' this ' zu vereinfachen . Sie verwenden das = & gt; Syntax, die wie ein Pfeil aussieht. Auch wenn ich nicht denke, dass es auf Diät gehen muss, nennen die Leute es „den Fettabbau “ (und Ruby-Enthusiasten wissen es vielleicht besser als „Hash Rock et“) - etwas, das man beachten sollte.

Wie sich das Schlüsselwort 'this' auf Pfeilfunktionen bezieht

Bevor wir uns eingehender mit den ES6-Pfeilfunktionen befassen , ist es wichtig, zunächst ein klares Bild davon zu erhalten, woran dies im ES5-Code gebunden ist.

Wenn sich das Schlüsselwort ' this ' in der Methode eines Objekts befindet (eine Funktion, die zu einem Objekt gehört), auf was würde es sich beziehen?

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

Richtig! Es würde sich auf das Objekt beziehen. Wir werden später erfahren, warum.

Was ist nun, wenn das Schlüsselwort ' this ' innerhalb der Funktion der Methode liegt?

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

Was hast du bekommen? Warten Sie, was ist mit unserem Hasen passiert ...?

Ah, haben Sie gedacht, dass sich dies auf die innere Funktion der Methode bezieht?

Vielleicht das Objekt selbst?

Sie sind weise, so zu denken, aber es ist nicht so. Gestatten Sie mir, Ihnen beizubringen, was mir die Ältesten der Kodierung einmal beigebracht hatten:

Coding Elder :Ach ja, t er - Code ist mit diesem stark. Es ist in der Tat praktisch zu glauben, dass das Schlüsselwort 'this' an die Funktion gebunden ist, aber die Wahrheit ist, dass 'this' jetzt außer Reichweite geraten ist… es gehört jetzt zu… “, er macht eine Pause, als würde er innere Turbulenzen erleben ,„ das Fensterobjekt .

Korrekt. Genau so ist es passiert.

Warum bindet ' dies ' an das Fensterobjekt? Da ' this ' immer auf den Eigentümer der Funktion verweist, in der es sich befindet, ist in diesem Fall - da es jetzt außerhalb des Gültigkeitsbereichs liegt - das Fenster / das globale Objekt.

Wenn es sich innerhalb der Methode eines Objekts befindet, ist der Eigentümer der Funktion das Objekt. Somit ist das Schlüsselwort ' this ' an das Objekt gebunden. Wenn es sich jedoch innerhalb einer Funktion befindet, entweder eigenständig oder innerhalb einer anderen Methode, bezieht es sich immer auf das Fenster / das globale Objekt.

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

Aber wieso…?

Dies wird als JavaScript-Eigenart bezeichnet. Dies bedeutet, dass etwas in JavaScript passiert, das nicht gerade einfach ist und nicht so funktioniert, wie Sie es sich vorstellen. Dies wurde auch von Entwicklern als schlechte Design-Wahl angesehen, die sie jetzt mit den Pfeilfunktionen von ES6 beheben.

Bevor wir fortfahren, ist es wichtig, zwei clevere Möglichkeiten zu kennen, wie Programmierer das " this " -Problem im ES5-Code lösen , insbesondere da Sie noch eine Weile auf ES5 stoßen werden (noch ist nicht jeder Browser vollständig auf ES6 migriert):

# 1 Erstellen Sie eine Variable außerhalb der inneren Funktion der Methode. Jetzt erhält die Methode 'forEach' Zugriff auf ' this ' und damit auf die Eigenschaften des Objekts und deren Werte. Dies liegt daran, dass ' this ' in einer Variablen gespeichert wird, während es sich noch im Bereich der direkten Methode 'showTasks' des Objekts befindet.

// 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 Verwenden Sie bind, um das Schlüsselwort ' this ', das sich auf die Methode bezieht, an die innere Funktion der Methode anzuhängen .

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

Und jetzt… Pfeilfunktionen! Der Umgang mit diesem Thema war noch nie einfacher und unkomplizierter! Die einfache ES6-Lösung:

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

Während sich in ES5 ' this ' auf das übergeordnete Element der Funktion bezieht, verwenden Pfeilfunktionen in ES6 das lexikalische Scoping - ' this ' bezieht sich auf den aktuellen umgebenden Bereich und nicht weiter. Somit wusste die innere Funktion nur an die innere Funktion zu binden und nicht an die Methode des Objekts oder das Objekt selbst.

So migrieren Sie Funktionen von ES5 nach 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 hast es geschafft! Gut gemacht! Einfach genug, oder? Hier sind einige weitere Beispiele, bei denen der fette dünne Pfeil verwendet wird, um Ihre Augen daran zu gewöhnen:

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

Wichtige Macken, die Sie bei der Verwendung von Pfeilfunktionen beachten sollten

Wenn Sie das Schlüsselwort 'new' mit => Funktionen verwenden, wird ein Fehler ausgegeben. Pfeilfunktionen können nicht als Konstruktor verwendet werden - normale Funktionen unterstützen das 'Neue' über den Eigenschaftsprototyp und die interne Methode [[Konstrukt]]. Pfeilfunktionen verwenden keines von beiden, daher gibt new (() => {}) einen Fehler aus.

Weitere zu berücksichtigende Macken:

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

Glückwunsch! Sie haben es durch Learn ES6 The Dope Way Teil II geschafft und jetzt haben Sie eine Grundlage für das Wissen über Pfeilfunktionen , die lexikalischen Vorteile, die es für ' dies ' bietet, und haben sich auch einige JavaScript-Eigenheiten angeeignet! :) :)

Halten Sie Ihre Weisheit auf dem neuesten Stand, indem Sie sie mögen und folgen, wenn Sie mehr erfahren. Learn ES6 The Dope Way wird bald auf Medium erscheinen!

Teil I: const, let & var

Teil II: (Pfeil) => Funktionen und 'dieses' Schlüsselwort

Part III: Template Literals, Spread Operators & Generators!

Part IV: Default Parameters, Destructuring Assignment, and a new ES6 method!

Part V: Classes, Transpiling ES6 Code & More Resources!

You can also find me on github ❤ //github.com/Mashadim