Дізнайтеся 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; синтаксис, який виглядає як стрілка. Незважаючи на те, що я не думаю, що потрібно сідати на дієту, люди називають це "жирною зарплатою" (а ентузіасти Рубі, можливо, знають це краще як "хеш-рок ") - щось, про що слід знати.

Як ключове слово '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. 

Що ти отримав? Стривай, що сталося з нашим зайчиком ...?

А, ти думав, що " це " стосується внутрішньої функції методу?

Можливо, сам предмет?

Ви мудро так думаєте, але це не так. Дозвольте навчити вас тому, чого колись навчили мене старійшини кодування:

Кодування Старший : « Ах так, T він код сильно з цим. Насправді практично думати, що ключове слово "this" прив'язується до функції, але правда в тому, що "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 ' і, отже, властивості об'єкта та їх значення. Це тому, що ' 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 слово « this » стосувалося батьківської функції, у ES6 функції стрілок використовують лексичний масштаб - « this » стосується поточного обсягу, а не подальшого. Таким чином, внутрішня функція знала, що зв’язується лише з внутрішньою функцією, а не з методом об’єкта чи самим об’єктом.

Як перенести функції з 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' з функціями =>, це призведе до помилки. Функції зі стрілками не можуть бути використані як конструктор - звичайні функції підтримують "нове" через прототип властивості та внутрішній метод [[Construct]]. Функції стрілок не використовують ні того, ні іншого, (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 Шлях допінгу незабаром стане середнім!

Частина I: const, let & var

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

Частина III: Шаблонні літерали, оператори розповсюдження та генератори!

Частина IV: Параметри за замовчуванням, призначення деструктуризації та новий метод ES6!

Частина V: Класи, перенесення коду ES6 та інші ресурси!

Ви також можете знайти мене на github ❤ //github.com/Mashadim