Стрелочные функции в JS
В этой статье вы познакомитесь со стрелочными функциями в JavaScript.
Стрелочные функции — одна из возможностей, которые появились в версии ES6.
Стрелочные функции позволяют более компактно и удобно записывать функциональные выражения.
Например, вот эту функцию:
// функциональное выражение
let x = function(x, y) {
return x * y;
}
можно записать с помощью стрелочной функции так:
// функциональное выражение, записанное через стрелочную функцию
let x = (x, y) => x * y;
Синтаксис
let имяФункции = (арг1, арг2, ...аргN) => { инструкции }
арг1, арг2, ...аргN
— аргументы функции.инструкции
— тело функции.
Если в теле функции предполагается только одна инструкция, стрелочную функцию можно записать в одну строку:
let имяФункции = (арг1, арг2, ...арг2) => выражение
Пример 1. Стрелочная функция без аргументов
Если функция не принимает никаких аргументов, нужно использовать пустые круглые скобки.
let greet = () => console.log('Привет');
greet(); // Вывод: Привет
Пример 2. Стрелочная функция с одним аргументом
Если у функции только один аргумент, круглые скобки можно опустить.
let greet = x => console.log(x);
greet('Привет'); // Вывод: Привет
Пример 3. Стрелочная функция в качестве выражения
Стрелочную функцию можно динамически создать и использовать ее в качестве выражения.
let age = 5;
let welcome = (age < 18) ?
() => console.log('Ребенок') :
() => console.log('Взрослый');
welcome(); // Вывод: Ребенок
Пример 4. Стрелочная функция в несколько строк
Если в теле функции несколько инструкций, их нужно заключить в фигурные скобки {}.
let sum = (a, b) => {
let result = a + b;
return result;
}
let result1 = sum(5,7);
console.log(result1); // Вывод: 12
Использование this со стрелочными функциями
Внутри обычной функции ключевое слово this
относится к функции, в которой оно вызывается.
Однако со стрелочными функциями this работает не так. У стрелочной функция нет собственного this. Поэтому всякий раз, когда вы вызываете this, она обращается к своей родительской области видимости.
Внутри обычной функции
function Person() {
this.name = 'Андрей',
this.age = 25,
this.sayName = function () {
// доступно
console.log(this.age);
function innerFunc() {
// this относится к глобальному объекту
console.log(this.age);
console.log(this);
}
innerFunc();
}
}
let x = new Person();
x.sayName();
Вывод
25 undefined Window {}
В этом примере this.age
внутри this.sayName()
доступен, потому что this.sayName()
— это метод объекта.
Однако innerFunc()
— это обычная функция, и this.age
недоступен, поскольку ссылается на глобальный объект (объект Window
в браузере). Следовательно, this.age
внутри функции innerFunc()
дает неопределенное значение.
Внутри стрелочной функции
function Person() {
this.name = 'Андрей',
this.age = 25,
this.sayName = function () {
console.log(this.age);
let innerFunc = () => {
console.log(this.age);
}
innerFunc();
}
}
const x = new Person();
x.sayName();
Вывод
25
25
В этом примере innerFunc()
определяется как стрелочная функция. А внутри стрелочной функции this
ссылается на родительскую область видимости. Следовательно, this.age
равно 25.
Привязка контекста к функции
У обычных функций есть привязка к аргументам (arguments binding). Поэтому когда вы передаете аргументы в обычную функцию, вы можете получить к ним доступ, используя ключевое слово arguments
.
let x = function () {
console.log(arguments);
}
x(4,6,7); // Вывод: Arguments [4, 6, 7]
У стрелочных функций нет привязки к аргументами.
Если вы пытаетесь получить доступ к аргументам стрелочной функции, JavaScript выдаст ошибку.
let x = () => {
console.log(arguments);
}
x(4,6,7);
// ReferenceError: Can't find variable: arguments
Чтобы решить эту проблему, можно использовать spread syntax ...
.
let x = (...n) => {
console.log(n);
}
x(4,6,7); // Вывод: [4, 6, 7]
Стрелочные функции с промисами и колбэками
Стрелочные функции можно использовать для упрощения создания промисов и колбэков.
Например, такой код:
// ES5
asyncFunction().then(function() {
return asyncFunction1();
}).then(function() {
return asyncFunction2();
}).then(function() {
finish;
});
можно переписать через стрелочные функции следующим образом:
// ES6
asyncFunction()
.then(() => asyncFunction1())
.then(() => asyncFunction2())
.then(() => finish);
Как не стоит использовать стрелочными функциями
1. Для создания методов внутри объекта.
let person = {
name: 'Андрей',
age: 25,
sayName: () => {
// this относится к глобальной области видимости .....
//
console.log(this.age);
}
}
person.sayName(); // Вывод: undefined
2. В качестве конструктора.
let Foo = () => {};
let foo = new Foo(); // TypeError: Foo is not a constructor
Примечание. Стрелочные функции работают не во всех браузерах. Узнать, поддерживает ли их ваш браузер, можно на странице JavaScript Arrow Function support.