Эквивалентность Arrow Functions и Functions в JavaScript: 11 ключевых моментов

Эквивалентность Arrow Functions и Functions в JavaScript: 11 ключевых моментов

1. Введение

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

2. Синтаксис

Синтаксис обычных функций и стрелочных функций немного отличается. Вот примеры обоих вариантов:

// Обычная функция
function sum(a, b) {
  return a + b;
}

// Стрелочная функция
const sum = (a, b) => a + b;

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

3. Связывание контекста

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

// Обычная функция
const obj = {
  name: 'John',
  sayHello: function() {
    console.log('Hello, ' + this.name);
  }
};

// Стрелочная функция
const obj = {
  name: 'John',
  sayHello: () => {
    console.log('Hello, ' + this.name); // this.name будет неопределенным
  }
};

4. Параметры функций

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

// Обычная функция
function sum(a, b) {
  console.log(arguments); // [1, 2, 3]
  console.log(a + b); // 3
}

sum(1, 2, 3);

// Стрелочная функция
const sum = (a, b) => {
  console.log(arguments); // ReferenceError: arguments is not defined
  console.log(a + b); // 3
};

sum(1, 2, 3);

5. Возвращаемые значения

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

// Обычная функция
function multiply(a, b) {
  return a * b;
}

console.log(multiply(2, 3)); // 6

// Стрелочная функция
const multiply = (a, b) => a * b;

console.log(multiply(2, 3)); // 6

6. Ключевое слово “new”

Ключевое слово new используется для создания новых экземпляров объектов в JavaScript. Обычные функции могут быть использованы в качестве конструкторов, вызываемых с помощью new, в то время как стрелочные функции не могут.

// Обычная функция
function Person(name) {
  this.name = name;
}

const john = new Person('John');
console.log(john.name); // John

// Стрелочная функция
const Person = (name) => {
  this.name = name; // TypeError: Cannot set property 'name' of undefined
};

const john = new Person('John');
console.log(john.name); // TypeError: john is undefined

7. Использование внутри других функций

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

// Обычная функция
function outer() {
  const inner = function() {
    console.log('Inner function');
  };

  inner();
}

outer(); // Inner function

// Стрелочная функция
const outer = () => {
  const inner = () => {
    console.log('Inner function');
  };

  inner();
}

outer(); // Inner function

8. Контекст выполнения

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

// Обычная функция
const obj = {
  name: 'John',
  sayHello: function() {
    console.log('Hello, ' + this.name);
  }
};

const sayHello = obj.sayHello;
sayHello(); // Hello, undefined

// Стрелочная функция
const obj = {
  name: 'John',
  sayHello: () => {
    console.log('Hello, ' + this.name); // this.name будет неопределенным
  }
};

const sayHello = obj.sayHello;
sayHello(); // Hello, undefined

9. Использование в методах массивов

Обычные функции и стрелочные функции могут быть использованы в методах массивов, таких как map, filter, reduce и других. Однако, в обычных функциях контекст выполнения может быть изменен внутри этих методов, а в стрелочных функциях значение this сохраняется из внешнего контекста.

const numbers = [1, 2, 3, 4, 5];

// Обычная функция
const squared = numbers.map(function(number) {
  return number * number;
});

console.log(squared); // [1, 4, 9, 16, 25]

// Стрелочная функция
const squared = numbers.map((number) => number * number);

console.log(squared); // [1, 4, 9, 16, 25]

10. Обработка событий

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

// Обычная функция
const button = document.querySelector('button');
button.addEventListener('click', function() {
  console.log('Clicked', this); // <button>...</button>
});

// Стрелочная функция
const button = document.querySelector('button');
button.addEventListener('click', () => {
  console.log('Clicked', this); // undefined
});

11. Вывод

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

Читайте так же  Как получить доступ к правильному this внутри callback в JavaScript?