Стрілочна функція (arrow function) і звичайна функція (function declaration/expression) в JavaScript мають кілька відмінностей:
Стрілочна функція використовується новий синтаксис () => {}
.
const add = (a, b) => a + b;
Якщо тіло стрілочної функції складається з одного виразу, можна опустити фігурні дужки {}
. У цьому випадку значення цього виразу буде автоматично повернуто без явного використання return
.
Звичайна функція використовується класичний синтаксис function
.
function add(a, b) {
return a + b;
}
Стрілкові функції не мають this
. Якщо відбувається звернення до this
, його значення береться ззовні. Це зручно в ситуаціях, коли потрібно зберегти контекст, наприклад, всередині обробників подій або функцій зворотного виклику (callback).
let team = {
title: "Our Team",
programmers: ["Alice", "Bob", "Charlie"],
showList() {
this.programmers.forEach(
programmer => console.log(this.title + ': ' + programmer)
);
}
};
team.showList();
// Output:
// Our Team: Alice
// Our Team: Bob
// Our Team: Charlie
Тут у forEach
використовується стрілкова функція, тому this.title
у ній має таке ж саме значення "Our Team"
.
Якби ми використали “звичайну” функцію, була б помилка:
'use strict'
let team = {
title: "Our Team",
programmers: ["Alice", "Bob", "Charlie"],
showList() {
this.programmers.forEach(function(programmer) {
// Error: Cannot read property 'title' of undefined
console.log(this.title + ': ' + programmer);
});
}
};
team.showList();
Помилка виникає через те, що forEach
запускає функції з this=undefined
за замовчуванням, тому ми намагаємося звернутися до undefined.title
.
Це не впливає на стрілкові функції, тому що вони не мають власного this
.
Відсутність this
призводить до ще одного обмеження: стрілкові функції не можуть бути використані як конструктори. Їх не можна викликати з new
.
const Foo = () => {};
const foo = new Foo(); // Викличе помилку
Стрілочні функції не мають власного об'єкта arguments
, тоді як звичайні функції мають.
const fn1 = () => {
console.log(arguments); // Викличе помилку
};
function fn2() {
console.log(arguments); // Доступ до всіх аргументів
}
Стрілкові функції не мають super
. Якщо super
доступний, то він береться із зовнішньої функції.
class Animal {
speak() {
console.log("The animal makes a sound");
}
}
class Dog extends Animal {
bark() {
// Використання звичайної функції - `this` залежить від того, як викликається функція
setTimeout(function() {
console.log("Regular function:");
super.speak(); // Це викличе помилку, оскільки `this` не визначено
}, 1000);
// Використання стрілочної функції - `this` лексично прив'язаний до екземпляра Dog
setTimeout(() => {
console.log("Arrow function:");
super.speak(); // Це працює, оскільки `this` посилається на екземпляр класу Dog
}, 2000);
}
}
const dog = new Dog();
dog.bark();