В JavaScript существует два основных способа определения функций: с помощью обычных функций и с помощью стрелочных функций. Разница между ними заключается в синтаксисе, поведении this и применении в качестве методов объектов, НО основное отличие и цель создания стрелочной функции заключается в том, что при build веб-приложения, уходит меньше времени на обработку стрелочных функций - это связанно с контекстом this
.
- Синтаксис:
Обычная функция определяется с помощью ключевого слова “function”, за которым следует имя функции, список параметров в скобках и тело функции в фигурных скобках.
function sum(a, b) {
return a + b;
}
Стрелочная функция определяется с помощью стрелки ”=>” между списком параметров и телом функции.
const sum = (a, b) => a + b;
- Поведение 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 в браузере)
}
};
- Применение в качестве методов объектов:
Обычные функции могут быть использованы в качестве методов объектов, т.е. функций, которые вызываются на объекте с помощью синтаксиса “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 и возможности использования в качестве методов объектов. Выбор между ними зависит от конкретных потребностей и контекста использования.
- Возвращаемое значение:
Если тело обычной функции содержит только одно выражение, то это выражение автоматически возвращается. Если тело обычной функции содержит несколько выражений, то возвращаемое значение должно быть явно указано с помощью ключевого слова “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;
};
- Аргументы по умолчанию:
function greet(name = "World") {
console.log("Hello, " + name);
}
Стрелочные функции также могут иметь аргументы по умолчанию.
const greet = (name = "World") => {
console.log("Hello, " + name);
};
Однако, у стрелочных функций есть ограничение: они не могут иметь переменные, которые называются “arguments”. Вместо этого, можно использовать оператор rest ”…” для получения всех аргументов функции.
- Количество аргументов:
В обычных функциях можно получить количество переданных аргументов с помощью свойства “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"
- Использование в массивах:
Обычные функции могут быть использованы в методах массивов (например, в методах 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]
- Использование в конструкторах:
Обычные функции могут быть использованы в качестве конструкторов объектов, т.е. функций, которые создают новые объекты с помощью ключевого слова “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;
};