Skip to content
This repository has been archived by the owner on May 26, 2020. It is now read-only.

Latest commit

 

History

History
258 lines (202 loc) · 8.13 KB

File metadata and controls

258 lines (202 loc) · 8.13 KB

Новые возможности JavaScript — Стрелочные функции

В ECMAScript 6 появился новый синтаксис функций.

// ECMAScript 5
var numbers = [-2, -1, 0, 1, 2];

var positiveIntegers = numbers.filter(function(number) {
  return number > 0;
});

console.log(positiveIntegers);
// Ожидаемый результат: [1, 2]
// ECMAScript 6
const numbers = [-2, -1, 0, 1, 2];

const positiveIntegers = numbers.filter(number => number > 0);

console.log(positiveIntegers);
// Ожидаемый результат: [1, 2]

Если вам нужна простая функция с одним аргументом, то синтаксис новых, стрелочных функций, — это просто идентификатор => выражение. Не нужно печатать ни function, ни return, ни круглых с фигурными скобками и точек с запятой.

// ECMAScript 5
function add(a, b) {
  return a + b;
}

console.log(add(1, 2));
// Ожидаемый результат: 3
// ECMAScript 6
const add = (a, b) => a + b;

console.log(add(1, 2));
// Ожидаемый результат: 3

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

// ECMAScript 5
var array = [1, 2, 3, 4, 5];

var total = array.reduce(function(acc, item) {
  return acc + item;
}, 0);

console.log(total);
// Ожидаемый результат: 15
// ECMAScript 6
const array = [1, 2, 3, 4, 5];

const total = array.reduce((acc, item) => acc + item, 0);

console.log(total);
// Ожидаемый результат: 15

Эффект при использовании обещаний может быть более заметным из-за нагромождения лишних блоков с фигурными скобами.

Без использования стрелочных функций:

fetch(url)
  .then(function(result) {
    return JSON.parse(result);
  })
  .then(function(result) {
    console.log(result);

    return result;
  })
  .then(function(result) {
    return processResultData(result);
  });

С использованием стрелочных функций:

fetch(url)
  .then(result => JSON.parse(result))
  .then(result => {
    console.log(result);

    return result;
  })
  .then(result => processResultData(result));

Также существует ещё одно отличие в поведении обычных и стрелочных функций.
У стрелочных функций нет собственного значения this. Внутри стрелочной функции this наследуется из окружающего лексического окружения (т. н. «лексический контекст»).

// ECMAScript 5
var person = {
  name: 'Tamik',
  showName: function() {
    return this.name;
  }
};

console.log(person.showName());
// Ожидаемый результат: "Tamik"
// ECMAScript 6
const person = {
  name: 'Tamik',
  showName: () => this.name,
};

console.log(person.showName());
// Ожидаемый результат: undefined
// ECMAScript 5
var person = {
  name: 'Tamik',
  showName: function() {
    setTimeout(function() {
      console.log(this.name)
    }, 1000);
  }
};

person.showName();
// Ожидаемый результат: undefined
// ECMAScript 6
const person = {
  name: 'Tamik',
  showName: function() {
    setTimeout(() => console.log(this.name), 1000);
  },
};

person.showName();
// Ожидаемый результат: "Tamik"

Стрелочные функции позволяет избавиться от большинства проблем с замыканиям (в которых не всегда «прозрачен» контекст). Но запомните: обычные функции получают значение this автоматически, неважно, нужно оно им, или нет. Стрелочные функции получают this из лексического окружения, которого у функции может не оказаться.

В ECMAScript 6 танцы с бубном вокруг this в большинстве случаев не нужны, если придерживаться этих правил:

  • Использовать обычные функции для методов, которые будут вызываться с использованием синтаксиса object.method(), таким способом эти функции получает вменяемый this от вызывающего кода;
  • Использовать стрелочные функции для всего остального. Это позволит вам избавиться от лишних проблем с замыканием, с которым часто сталкиваются в функциях обратного вызова (т.н. «callback»).

Также ECMAScript 6 предоставляет более краткий способ записи методов в литералах объектов, так что код можно писать ещё проще. Подробнее об этом можно прочитать в разделе «Расширение объектных литералов».

Ещё небольшие отличия стрелочных функций от обычных.

Работа с массивами и объектами несколько отличается:

// ECMAScript 5
function getPerson() {
  return {
    name: 'Tamik',
    age: 19
  };
}

function getServices() {
  return ['Market', 'Maps', 'Music'];
}

console.log(getPerson());
// Ожидаемый результат: {name: "Tamik", age: 19}
console.log(getServices());
// Ожидаемый результат: ["Market", "Maps", "Music"]
// ECMAScript 6
const getPerson = () => ({
  name: 'Tamik',
  age: 19,
});

const getServices = () => (['Market', 'Maps', 'Music']);

console.log(getPerson());
// Ожидаемый результат: {name: "Tamik", age: 19}
console.log(getServices());
// Ожидаемый результат: ["Market", "Maps", "Music"]

Стрелочная функция может быть IIFE1.

// ECMAScript 5
(function() {
  // ...
})();
// ECMAScript 6
(() => {
  // ...
})();

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

// ECMAScript 6
const Person = () => console.log('Construct!');

const person = new Person(); // Ошибка! Person не является конструктором

Не рекомендуется использовать методы bind, call и apply, так как в стрелочных функциях не имеет смысла изменять контекст. Присваивание контекста при помощи bind создаёт новую функцию, которой присваивается заданный контекст. В итоге увеличивается потребление памяти вашего приложения.


IIFE1 (Immediately Invoked Function Expression) — функция, которая выполняется сразу же после того как была определена.