Незадоволений іншими відповідями. Відповідь, яка проголосувала вгорі, станом на 2019/3/13 фактично неправильна.
Короткий короткий варіант того, що =>
означає, що це ярлик, який записує функцію І для прив'язки її до струмуthis
const foo = a => a * 2;
Фактично це ярлик для
const foo = function(a) { return a * 2; }.bind(this);
Ви можете бачити всі речі, які скоротилися. Нам не потрібні function
, ані return
ні, .bind(this)
ні дужки чи дужки
Трохи довший приклад функції стрілки може бути
const foo = (width, height) => {
const area = width * height;
return area;
};
Показавши, що якщо ми хочемо кілька аргументів функції, нам потрібні круглі дужки, і якщо ми хочемо написати більше, ніж один вираз, нам потрібні дужки і явне return
.
Важливо зрозуміти .bind
частину, і це велика тема. Це стосується того, що this
означає JavaScript.
ВСІ функції мають неявний параметр, який називається this
. Як this
встановлюється при виклику функції, залежить від того, як вона називається.
Брати
function foo() { console.log(this); }
Якщо ви називаєте це нормально
function foo() { console.log(this); }
foo();
this
буде глобальним об’єктом.
Якщо ви перебуваєте в суворому режимі
`use strict`;
function foo() { console.log(this); }
foo();
// or
function foo() {
`use strict`;
console.log(this);
}
foo();
Це буде undefined
Ви можете встановити this
безпосередньо, використовуючи call
абоapply
function foo(msg) { console.log(msg, this); }
const obj1 = {abc: 123}
const obj2 = {def: 456}
foo.call(obj1, 'hello'); // prints Hello {abc: 123}
foo.apply(obj2, ['hi']); // prints Hi {def: 456}
Ви також можете встановити this
неявно за допомогою оператора точок.
function foo(msg) { console.log(msg, this); }
const obj = {
abc: 123,
bar: foo,
}
obj.bar('Hola'); // prints Hola {abc:123, bar: f}
Проблема виникає, коли ви хочете використовувати функцію як зворотний дзвінок або слухач. Ви робите клас і хочете призначити функцію як зворотний виклик, який отримує доступ до екземпляра класу.
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click', function() {
console.log(this.name); // won't work
});
}
}
Код, наведений вище, не буде працювати, оскільки коли елемент запускає подію та викликає функцію, this
значення не буде екземпляром класу.
Одним із поширених способів вирішити цю проблему є використання .bind
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click', function() {
console.log(this.name);
}.bind(this); // <=========== ADDED! ===========
}
}
Тому що синтаксис стрілки робить те саме, що ми можемо написати
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click',() => {
console.log(this.name);
});
}
}
bind
ефективно робить нову функцію . Якби bind
не існувало, ви могли в основному зробити так, як це ви хочете
function bind(funcitonToBind, valueToUseForThis) {
return function(...args) {
functionToBind.call(valueToUseForThis, ...args);
};
}
У старих JavaScript без оператора розповсюдження це було б
function bind(funcitonToBind, valueToUseForThis) {
return function() {
functionToBind.apply(valueToUseForThis, arguments);
};
}
Розуміння цього коду вимагає розуміння закриттів, але коротка версія - bind
це нова функція, яка завжди викликає оригінальну функцію зі this
значенням, яке було пов'язане з нею. Функція стрілки робить те саме, оскільки вони є ярликомbind(this)