В JavaScript существует два основных способа определения функций: с помощью обычных функций и с помощью стрелочных функций. Разница между ними заключается в синтаксисе, поведении this и применении в качестве методов объектов, НО основное отличие и цель создания стрелочной функции заключается в том, что при build веб-приложения, уходит меньше времени на обработку стрелочных функций - это связанно с контекстом this.

  1. Синтаксис:

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

function sum(a, b) {
  return a + b;
}

Стрелочная функция определяется с помощью стрелки ”=>” между списком параметров и телом функции.

const sum = (a, b) => a + b;
  1. Поведение this:

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

const obj = {
  name: "John",
  greet: function () {
    console.log("Hello, " + this.name); // this ссылается на объект obj
  },
  greetArrow: () => {
    console.log("Hello, " + this.name); // this ссылается на глобальный объект (window в браузере)
  }
};
  1. Применение в качестве методов объектов:

Обычные функции могут быть использованы в качестве методов объектов, т.е. функций, которые вызываются на объекте с помощью синтаксиса “object.method()“. Стрелочные функции не могут быть использованы в качестве методов объектов, потому что значение this в них не зависит от объекта, на котором они вызываются.

const obj = {
  name: "John",
  greet: function () {
    console.log("Hello, " + this.name);
  },
  greetArrow: () => {
    console.log("Hello, " + this.name); // this ссылается на глобальный объект (window в браузере)
  }
};
 
obj.greet(); // Вызывает метод greet() с помощью объекта obj
obj.greetArrow(); // Ошибка: this.name is undefined

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

  1. Возвращаемое значение:

Если тело обычной функции содержит только одно выражение, то это выражение автоматически возвращается. Если тело обычной функции содержит несколько выражений, то возвращаемое значение должно быть явно указано с помощью ключевого слова “return”.

function double(x) {
  return x * 2;
}
 
function multiply(x, y) {
  const result = x * y;
  return result;
}

В стрелочной функции, если тело содержит только одно выражение, то оно автоматически возвращается без использования ключевого слова “return”. Если тело содержит несколько выражений, то возвращаемое значение должно быть явно указано с помощью ключевого слова “return”.

const double = x => x * 2;
 
const multiply = (x, y) => {
  const result = x * y;
  return result;
};
  1. Аргументы по умолчанию:
function greet(name = "World") {
  console.log("Hello, " + name);
}

Стрелочные функции также могут иметь аргументы по умолчанию.

const greet = (name = "World") => {
  console.log("Hello, " + name);
};

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

  1. Количество аргументов:

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

function greet() {
  console.log("Number of arguments:", arguments.length);
}
 
const greetArrow = (...args) => {
  console.log("Number of arguments:", args.length);
};
 
greet("John", "Doe"); // Выводит "Number of arguments: 2"
greetArrow("John", "Doe"); // Выводит "Number of arguments: 2"
  1. Использование в массивах:

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

const arr = [1, 2, 3, 4];
const squares = arr.map(function (x) {
  return x * x;
});

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

const arr = [1, 2, 3, 4];
const squares = arr.map(x => x * x);

Однако, в этом случае следует обратить внимание на поведение this. Если стрелочная функция используется в методе массива в качестве колбэка, то значение this будет определяться лексически, т.е. оно будет наследоваться от окружающего контекста.

const obj = {
  name: "John",
  numbers: [1, 2, 3, 4],
  double: function () {
    return this.numbers.map(x => x * 2);
  }
};
 
console.log(obj.double()); // Выводит [2, 4, 6, 8]
  1. Использование в конструкторах:

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

function Person(name, age) {
  this.name = name;
  this.age = age;
}
 
const john = new Person("John", 30);
console.log(john.name, john.age); // Выводит "John 30"

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

const Person = (name, age) => {
  this.name = name; // Ошибка: this is not defined
  this.age = age;
};

Назад