Стрелочная функция в JavaScript — основы использования

В этом руководстве вы узнаете основы и как использовать стрелочную функцию JavaScript для написания более лаконичного кода для функциональных выражений.

Стрелочные функции ES6 предоставляют вам альтернативный способ написать более короткий синтаксис по сравнению с выражением функции.

В следующем примере определяется функциональное выражение, которое возвращает сумму двух чисел:

let add = function(x, y) {
    return x + y;
};
console.log(add(10, 20)); // 30

Следующий пример эквивалентен приведенному выше функциональному выражению add(), но вместо него используется функция стрелки:

let add =(x, y) => x + y; 
console.log(add(10, 20)); // 30;

В этом примере стрелочная функция имеет одно выражение x + y, поэтому она возвращает результат выражения.

Однако, если вы используете блочный синтаксис, вам необходимо указать ключевое слово return :

let add =(x, y) => { return x + y; };

Оператор typeof возвращает function, указывающую тип стрелочной функции.

console.log(typeof add);
 // function

Стрелочная функция также является экземпляром типа Function, как показано в следующем примере:

console.log(add instanceof Function); // true

С несколькими параметрами

Если стрелочная функция имеет два или более параметра, используется следующий синтаксис:

(p1, p2, ..., pn) => expression;

Следующее выражение:

=> expression

Эквивалентно следующему выражению:

=> { return expression; }

Например, чтобы отсортировать массив чисел в порядке убывания, вы используете метод sort() объекта массива следующим образом:

let numbers = [4, 2, 6];
numbers.sort(function(a, b) {
    return b - a;
});
console.log(numbers); // [6,4,2]

Код более лаконичен благодаря синтаксису стрелочной функции:

let numbers = [4,2,6]; 
numbers.sort((a,b) => b - a); 
console.log(numbers); // [6,4,2]

С одним параметром

Если стрелочная функция принимает один параметр, используется следующий синтаксис:

(p1) => { statements }

Обратите внимание, что вы можете опустить круглые скобки следующим образом:

p => { statements }

В следующем примере стрелочная функция используется в качестве аргумента метода map(), который преобразует массив строк в массив длин строк.

let names = ['John', 'Mac', 'Peter']; 
let lengths = names.map(name => name.length); 
console.log(lengths);

Выход:

[ 4, 3, 5 ]

Без параметров

Если стрелочная функция не имеет параметра, вам нужно использовать круглые скобки, например:

() => { statements }

Например:

let logDoc =() => console.log(window.document); 
logDoc();

Разрыв строки между определением параметра и стрелкой

JavaScript не позволяет разрывать строку между определением параметра и стрелкой( => ) в стрелочной функции.

Например, следующий код вызывает SyntaxError :

let multiply =(x,y) 
=> x * y;

Однако следующий код работает отлично:

let multiply =(x,y) => 
x * y;

JavaScript позволяет вам использовать разрывы строк между параметрами, как показано в следующем примере:

let multiply =( 
x, 
y 
) => 
x * y;

Операторы и выражения в теле функции стрелки

В JavaScript выражение оценивается как значение, как показано в следующем примере.

10 + 20;

Оператор выполняет определенную задачу, например:

if(x === y) { 
    console.log('x equals y'); 
}

Если вы используете выражение в теле стрелочной функции, вам не нужно использовать фигурные скобки.

let square = x => x * x;

Однако если вы используете оператор, вы должны заключить его в пару фигурных скобок, как в следующем примере:

let except = msg => { 
    throw msg; 
};

Функции стрелки и объектный литерал

Рассмотрим следующий пример:

let setColor = function (color) {
    return {value: color}
};

let backgroundColor = setColor('Red');
console.log(backgroundColor.value); // "Red"

Выражение функции setColor() возвращает объект, у которого свойство value установлено в качестве аргумента color.

Если вы используете следующий синтаксис для возврата литерала объекта из функции стрелки, вы получите ошибку:

p => {object:literal}

Например, следующий код вызывает ошибку.

let setColor = color => {value: color };

Поскольку литерал блока и объекта использует фигурные скобки, механизм JavasScript не может отличить блок от объекта.

Чтобы исправить это, вам нужно заключить литерал объекта в круглые скобки следующим образом:

let setColor = color =>({value: color });

Отличия стрелочной функции от обычной

Есть два основных отличия между стрелочной функцией и обычной функцией:

  1. Во-первых, в стрелочной функции this, arguments, super, new.target являются лексическими. Это означает, что стрелочная функция использует эти переменные(или конструкции) из объемлющей лексической области видимости.
  2. Во-вторых, функцию стрелки нельзя использовать в качестве конструктора функции. Если вы используете ключевое слово new для создания нового объекта из функции стрелки, вы получите сообщение об ошибке.

Стрелочные функции и this значение

В JavaScript новая функция определяет собственное значение this. Однако это не относится к стрелочной функции.

Следующий пример:

function Car() {
    this.speed = 0;

    this.speedUp = function (speed) {
        this.speed = speed;
        setTimeout(function () {
            console.log(this.speed); // undefined
        }, 1000);

    };
}

let car = new Car();
car.speedUp(50);

Внутри анонимной функции setTimeout() значение this.speed не undefined. Причина в том, что this анонимной функции затеняет this метода speedUp().

Чтобы исправить это, вы присваиваете this значение переменной, которая не затеняет внутри анонимной функции, следующим образом:

function Car() {
    this.speed = 0;

    this.speedUp = function (speed) {
        this.speed = speed;
        let self = this;
        setTimeout(function () {
            console.log(self.speed);
        }, 1000);

    };
}

let car = new Car();
car.speedUp(50); // 50;

В отличие от анонимной функции, стрелочная функция захватывает значение this окружающего контекста, а не создает свой собственный контекст this. Следующий код должен работать как положено:

function Car() {
    this.speed = 0;

    this.speedUp = function (speed) {
        this.speed = speed;
        setTimeout(
            () => console.log(this.speed),
            1000);

    };
}

let car = new Car();
car.speedUp(50); // 50;

Объект arguments

Стрелочная функция не имеет объекта arguments. Например:

function show() {
    return x => x + arguments[0];
}

let display = show(10, 20);
let result = display(5);
console.log(result); // 15

Функция стрелки внутри функции showMe() ссылается на объект arguments. Однако этот объект arguments принадлежит функции show(), а не функции стрелки.

Кроме того, у стрелочной функции нет ключевого слова new.target.

Свойство прототипа

Когда вы определяете функцию с помощью ключевого слова function, функция имеет свойство, называемое prototype :

function dump( message ) {
    console.log(message);
}
console.log(dump.hasOwnProperty('prototype')); // true

Однако стрелочные функции не имеют свойства prototype :

let dump = message => console.log(message); 
console.log(dump.hasOwnProperty('prototype')); // false

Хорошей практикой является использование стрелочных функций для обратных вызовов и замыканий, поскольку синтаксис таких функций чище.

Заключение

  • Используйте (...args) => expression; для определения стрелочной функции.
  • Используйте (...args) => { statements }, чтобы определить функцию стрелки, которая имеет несколько операторов.
  • Функция стрелки не имеет привязки к this или super.
  • У стрелочной функции нет объекта arguments, ключевого слова new.target и свойства prototype.
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript