Научете ES6 The Dope Way Част II: Функции със стрелки и ключовата дума 'this'

Добре дошли в част II на Learn ES6 The Dope Way, поредица, създадена, за да ви помогне лесно да разберете ES6 (ECMAScript 6)!

И така, какво по дяволите е => ; ?

Вероятно сте виждали тези странни на вид египетски символи на йероглифи тук и там, особено в кода на някой друг, където в момента отстранявате грешки в проблем с ключовите думи „ този“ . След един час бърникане, сега се разхождате в лентата за търсене на Google и дебнете Stack Overflow. Звучи познато?

Нека заедно да разгледаме три теми в Learn ES6 The Dope Way Part II:

  • Как ключовата дума ' this ' е свързана с => .
  • Как да мигрирам функции от ES5 към ES6.
  • Важни странности, които трябва да знаете, когато използвате => .

Функции на стрелките

Функциите със стрелки са създадени, за да опростят обхвата на функциите и да направят използването на ключовата дума ' this ' много по-лесно. Те използват = & gt; синтаксис, който прилича на стрелка. Въпреки че не мисля, че е необходимо да се подлагаме на диета, хората го наричат „мазнините “ (а ентусиастите на Ruby може да го знаят по-добре като „hash rock et“) - нещо, което трябва да знаете.

Как ключовата дума 'this' е свързана със стрелковите функции

Преди да се потопите дълбоко в ES6 стрелка функции, важно е първо да се получи ясна представа за това какво това "се свързва в ES5 код.

Ако ключовата дума ' this ' е в метода на обекта (функция, която принадлежи на обект), на какво би се отнасяла?

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

Правилно! Това би се отнасяло за обекта. По-късно ще стигнем до защо.

Ами ако ключовата дума ' this ' е вътре във функцията на метода?

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

Какво получи? Чакай, какво се случи с нашето зайче ...?

А, мислехте ли, че „ това “ се отнася до вътрешната функция на метода?

Може би самият обект?

Разумно е да мислите така, но не е така. Позволете ми да ви науча на това, което някога ме бяха научили старейшините на кодирането:

Кодиране на старейшина : " Ах, да, т той код е силна с това. Наистина е практично да се мисли, че ключовата дума 'this' се свързва с функцията, но истината е, че 'this' вече е излязла от обхвата ... Вече принадлежи на ... ”, той прави пауза, сякаш изпитва вътрешен смут ,“ прозоречния обект .

Това е вярно. Точно така се случи.

Защо „ това “ се обвързва с обекта на прозореца? Тъй като ' това ', винаги се позовава на собственика на функцията, в която се намира, за този случай - тъй като вече е извън обхвата - прозореца / глобалния обект.

Когато е вътре в метода на обекта - собственикът на функцията е обектът. По този начин ключовата дума ' this ' е свързана с обекта. И все пак, когато е вътре във функция, самостоятелна или в рамките на друг метод, тя винаги ще се позовава на прозореца / глобалния обект.

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

Но защо…?

Това е известно като JavaScript странност, което означава нещо, което просто се случва в JavaScript, което не е съвсем просто и не работи по начина, по който бихте мислили. Това също беше оценено от разработчиците като лош избор на дизайн, който сега те отстраняват с функциите на стрелките на ES6.

Преди да продължим, важно е да сме наясно с два интелигентни начина, по които програмистите решават проблема „ този “ в рамките на ES5 кода, особено след като ще продължите да се сблъсквате с ES5 известно време (все още не всеки браузър е мигрирал напълно към ES6):

# 1 Създайте променлива извън вътрешната функция на метода. Сега методът "forEach" получава достъп до " this " и по този начин свойствата на обекта и техните стойности. Това е така, защото ' това ' се съхранява в променлива, докато все още е в обхвата на директния метод на обекта '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 Използвайте bind, за да прикачите ключовата дума ' this ', която се отнася до метода, към вътрешната функция на метода.

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

А сега представяме ... Функции със стрелки! Справянето с „ този “ проблем никога не е било по-лесно и по-лесно! Простото ES6 решение:

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

Докато в ES5 „ това “ се отнася до родителя на функцията, в ES6 функциите със стрелки използват лексикален обхват - „ това “ се отнася до текущия обхват на обкръжението и не повече. По този начин вътрешната функция знаеше да се свързва само с вътрешната функция, а не с метода на обекта или самия обект.

Как да мигрирам функции от ES5 към 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");

Направи го! Добра работа! Достатъчно просто, нали? Ето още няколко примера за използване на по-дебелата кльощава стрелка, за да свикнете с очите си:

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

Важни странности, с които трябва да сте наясно, когато използвате функциите със стрелки

Ако използвате ключовата дума 'new' с => функции, тя ще изведе грешка. Функциите със стрелки не могат да се използват като конструктор - нормалните функции поддържат 'новото' чрез прототипа на свойството и вътрешния метод [[Конструктиране]]. Функциите със стрелки не използват нито едното, така и другото (() => {}) извежда грешка.

Допълнителни странности, които да разгледате:

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

Поздравления! Преминахте през Learn ES6 The Dope Way Part II и сега имате основа за знания за функциите на стрелките, лексикалните предимства, които дава на „ това “, а също така си взехте някои странни умения за JavaScript! :)

Поддържайте своята мъдрост актуализирана, като харесвате и следвате, тъй като повече Научете ES6 The Dope Way идва скоро до Medium!

Част I: const, let & var

Част II: (Стрелка) => функции и ключова дума 'this'

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