Разница между традиционными функциями и стрелочными функциями в JavaScript
- вторник, 30 мая 2023 г. в 00:00:12
Не заблуждайтесь, способы объявления функций в Javascript отличаются не только компактностью и элегантным синтаксисом.
Стрелочные функции — это относительно новая функция, реализованная в ES6 ( ECMAScript 6 ), которая, на наш взгляд, является просто более кратким и элегантным синтаксисом для объявления функциональных выражений в JavaScript. Хотя традиционные функции и функции стрелок работают схожим образом, мы должны остерегаться некоторых различий, которые могут быть незаметны.
Разница в синтаксисе между двумя моделями общеизвестна, поскольку в стрелочной функции становится возможным значительно сократить количество строк, присутствующих в объявлении функции, особенно если это уже простая функция. См. примеры:
Представьте себе функцию, которая берет имя пользователя и выводит его в консоль. Традиционным способом мы могли бы объявить это так:
function sayMyNane(name){
console.log(`My name is ${name}!`);
}
sayMyNane('Ernane'); // => My name is Ernane.
Со стрелочными функциями из ES6 мы могли бы сделать это следующим образом:
const sayMyName = (name) => {
console.log(`My name is ${name}`);
};
sayMyName("Ernane"); // => My name is Ernane.
Помня, что в случае со стрелочными функциями фигурные скобки необходимы только в том случае, если присутствует выражение, то же правило применяется и к скобкам, поскольку они необходимы только в том случае, если необходимо передать более одного аргумента. Таким образом, мы могли бы уменьшить его еще больше и записать приведенный выше пример следующим образом:
const sayMyName = (name) => console.log(`My name is ${name}`);
sayMyName("Ernane"); // => My name is Ernane.
Просто, не так ли? Таким образом, мы можем увидеть, как стрелочная функция может облегчить объявление определенной функции из-за своего синтаксиса и при этом вернуть тот же результат, что и обычное объявление.
В отличие от традиционного объявления, стрелочные функции не имеют собственного элемента this , поскольку значение this внутри стрелочной функции остается неизменным на протяжении всего жизненного цикла функции и всегда привязано к значению this в ближайшей традиционной родительской функции.
Это стало немного странно? Позвольте мне попытаться упростить с примером:
Возвращаясь к примеру, использованному в предыдущем разделе, представьте, что у нас есть объект person
, имя которого определено как один из его атрибутов, и функция, которая выводит имя этого конкретного человека в консоль. В зависимости от типа используемой функции она не сможет правильно получить доступ к родительскому объекту, имеющему запрошенный атрибут имени , и, следовательно, ее возврат будет undefined
.
let person = {
name: "Ernane Ferreira",
sayMyName: () => console.log(`My name is ${this.name}.`),
};
person.sayMyName(); // => My name is .
В случае объявления функции в традиционной модели это будет работать как положено и мы правильно получим искомый атрибут.
let person = {
name: "Ernane Ferreira",
sayMyName: function () {
console.log(`My name is ${this.name}.`);
},
};
person.sayMyName(); // => My name is Ernane Ferreira.
Объект arguments — это локальная переменная, доступная внутри всех функций, и это то, что делает ссылку возможными аргументами функции внутри нее, используя объект arguments. Однако стрелочные функции не имеют ссылки на arguments
объект:
const showArguments = () => console.log(arguments);
showArguments(1, 2, 3) // => ReferenceError: arguments is not defined.
В случае обычной функции мы можем легко получить доступ к списку аргументов, переданных в качестве параметра при вызове функции:
function showArguments(){
console.log(arguments);
}
showArguments(1, 2, 3) // => Arguments(3) [1, 2, 3]
Оператор new позволяет создавать экземпляры определяемого пользователем типа объекта или одного из определяемых пользователем типов. внутренних объектов, которые имеют функцию конструктора . Традиционные функции являются конструируемыми и могут быть вызваны с помощью оператораnew
. С другой стороны, стрелочные функции являются вызываемыми, а не конструируемыми, то есть эти функции никогда не могут использоваться в качестве функций-конструкторов и никогда не могут вызываться с помощью оператора new
.
Поэтому для такого типа выполнения в традиционных функциях мы получаем следующий результат выполнения:
function sayMyName(name) {
console.log(`My name is ${name}`);
}
new sayMyName("Ernane"); // => Ernane
Что касается стрелочных функций :
const sayMyName = (name) => console.log(`My name is ${name}`);
new sayMyName("Ernane"); // => Uncaught TypeError: sayMyName is not a constructor
Стрелочные функции не допускают дублирования имен параметров, но традиционные функции допускают зависимость от применения или неприменения строгого режима ( Strict Mode ) в реализации кода. Например, приведенный ниже JavaScript полностью действителен:
function addTwoNumbers(x, x){
console.log(x+x);
}
addTwoNumbers(1,1); // => 2
Однако тот же код с примененным строгим режимом больше недействителен:
"use strict";
function addTwoNumbers(x, x) {
console.log(x + x);
}
// => Uncaught SyntaxError: Duplicate parameter name not allowed in this context
При использовании стрелочных функций это происходит независимо от того, применяется ли строгий режим. В обоих случаях выполнение недействительно:
const addTwoNumbers = (x, x) => console.log(x+x);
// => SyntaxError: Uncaught SyntaxError: Duplicate parameter name not allowed in this context.
Таким образом, всегда полезно уделять пристальное внимание использованию стрелочных функций вместо традиционных функций. Хотя их синтаксис очень приятен, в них есть некоторые моменты, к которым мы должны быть внимательны, чтобы не пропустить их.
В любом случае рекомендуется дальнейшее изучение этого вопроса. Как всегда, я оставлю ниже несколько рекомендательных ссылок для углубления темы.
Надеюсь, вам понравился этот пост и он помог вам найти то, что вы искали!