Понимание cтрелочных функций JavaScript

В редакции 2015 года стандарта ECMAScript (ES6) на языке JavaScript были добавлены функции стрелок. Аналогично лямбда-функциям в Python, стрелочные функции пользуются новым подходом к представлению анонимных вызовов функций.

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

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

Функции распознавания

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

Идея объявления функций и выражений функций была представлена ​​в первом уроке этой серии, “Как определить функции в JavaScript”. Именованная функция, в которой используется ключевое слово function, называется объявлением функции. Перед выполнением любого определения кода функции запускаются в контексте выполнения. 

Сумма функций, возвращающая сумму двух аргументов, включающая в себя следующее значение:

function sum(c, d) { 
return c + d 
}

Благодаря подъему, вы можете использовать функцию для функции объявления:

function sum (3, 4) 
sum(c, d) { 
return c + d 
}

Результат выполнения этого кода будет предложено:

Output 
7

Записывая в журнал саму функцию, вы можете узнать ее имя:

console.log(sum)

После этого функция будет возвращена вместе с ее именем:

Output 
ƒ sum(c, d) { 
возвращает c + d 
}

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

В Настоящее время использование запишем ту же функцию как анонимное функциональное выражение:

const sum = функция (c, d) { 
return c + d 
}

Теперь вы наделили константу суммы анонимной плотности. Если вы устанавливаете функцию до того, как она будет объявлена, возникнет ошибка:

sum(3, 4) 
const sum = function (c, d) { 
return c + d 
}

Выполнение этой функции к следующему результату:

Output: 
Непойманная ссылка 
Error: Не удается получить доступ к 'сумме' до инициализации.

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

const sum = function (c, d) { 
return c + d 
} 
console.log(sum)

В результате вы увидите следующее:

Выход 
ƒ (c, d) { 
return c + d 
}

Вместо того, чтобы быть именованной массой, величина суммы является анонимной.

Несмотря на то, что ключевое слово function может быть использовано в Российской Федерации для обозначения функций, на практике это не принято делать. Чтобы упростить отладку трассировки стековых ошибок, именование функционального выражения является одной из причин, по которой вы хотите это сделать.

Рассмотрим приведенную ниже функцию, которая выдает ошибку, если какие-либо из требуемых параметров опускаются:

const sum = function namedSumFunction(c, d) { 
if (!c || !d) throw new Error(' Параметры.') 
return c + d 
} 
sum();

Функция названа в выделенной части, и если один из параметров отсутствует, функция использует оператор или ||, чтобы выбросить объект ошибки.

В результате выполнения этого кода вы получите результат, полученный ниже:

Вывод Невозникшая 
ошибка: Требуются параметры. 
at namedSumFunction (<анонимно>:3:23) 
at <анонимно>:1:1

В этой ситуации знание имени функции помогает быстро решить проблему.

Выражение анонимной функции, в котором используется синтаксис «толстой стрелки» (=>), называется выражением стрелочной функции.

Используем синтаксис стрелочной функции, чтобы переписать функцию Sum:

const sum = (c, d) => { 
return c + d 
}

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

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

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

В этом разделе вы рассмотрите примеры, иллюстрирующие каждую ситуацию.

Значение this

В терминах JavaScript это часто воспринимается как затрагиваемая тема. В статье Understanding This, Bind, Call и Apply в JavaScript заменить функцию this и то, как она может неявно подразумеваться в зависимости от того, использует ли ее программа в глобальном масштабе, как метод внутри, как конструктор объекта функции или класса, или как обработчик событий ДОМ.

Значение этого параметра в функциях строк является лексическим, то есть оно зависит от контекста (лексического окружения).

Различие между обычными и стрелочными функциями, обрабатывающими это, будет означать в последующем. Атрибуты фразы и числа, указанные в следующем объекте printNumbers. Кроме того, в объекте есть метод цикла, который печатает текстовые фразы и значение ценности в числах:

const printNumbers = { 
phrase: 'Текущее значение:', 
number: [1, 2, 3, 4], 
loop() { 
this.numbers.forEach(function (number) { 
console.log(this.phrase, number)
    }) 
  }, 
}

На каждой итерации цикла функция должна выводить структуру и номер цикла. Однако фраза не определена в выводе функции:

printNumbers.loop()

Результат будет выглядеть следующим образом:

Output
неопределенный 1 
неопределенный 2 
неопределенный 3 
неопределенный 4

Это показывает, что это в анонимной функции, переданной в метод forEach, не относится к объекту printNumbers, поскольку this.phrase не определена. Это сделано для того, чтобы обычная функция не могла получить свое значение из объекта printNumbers, который является областью видимости среды.

В предыдущих версиях JavaScript должен был использоваться метод bind, который обнаруживает это значение. До появления ES6 этот подход часто использовался в некоторых предыдущих версиях фреймворков, таких как React.

Чтобы зафиксировать функцию, используйте привязку:

const printNumbers = { 
phrase: 'Текущее значение:', 
number: [1, 2, 3, 4], 
loop() {
// Привязка `this` из printNumbers к внутренней функции forEach 
this.numbers.forEach( 
function (number) { 
console.log(this.phrase, number) 
}.bind(this), 
)
},
}
printNumbers.loop()

Это обеспечивает требуемый результат:

Вывод 
Текущее значение: 1 
Текущее значение: 2 
Текущее значение равно: 3 
Текущее значение равно: 4

Стрелочные функции дают более удобное решение этой проблемы. вызов, который представляет собой значение, основанное на словарной видимости области, приведенный ниже пример сочетания, как встроенная функция, вызываемая в forEach, теперь может получить доступ к атрибутам внешнего объекта printNumbers:

const printNumbers = { фраза: 'Текущее значение:', числа: [1, 2, 3, 4], loop() { this.numbers.forEach((number) => { console.log(this.phrase, number)
})
},
}
printNumbers.loop()

Это обеспечивает желаемый результат:

Вывод
Текущее значение: 1 
Текущее значение: 2 
Текущее значение равно: 3 
Текущее значение равно: 4

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

Стрелочные функции как объектные методы

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

const printNumbers = { 
phrase: 'Текущее значение:', 
number: [1, 2, 3, 4], 
for: () => { 
this.numbers.forEach((number) => { 
console.log(this.phrase , количество)
}) 
}, 
}

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

использовать метод loop(): 
printNumbers.loop()

Результат будет выглядеть следующим образом:

Output
Uncaught TypeError: Не удается прочитать свойство forEach неопределенного

Метод функции arrow в случае использования ищет его во внешней видимой области-Window, поскольку объект не образует лексическую область открытой. Он выдает ошибку, так как объект Окно не имеет атрибута номера. Использование обычных функций в качестве методов объекта по умолчанию часто более безопасно.

Для стрелочных функций не существует конструктора или прототипа

В ходе наблюдения за этой серией, “Понимание прототипов и наследования в JavaScript”, было выявлено, как функции и классы имеют свойства прототипа, которые JavaScript использует в качестве моделей для клонирования и наследования.

свойство прототипа, которое было автоматически присвоено, чтобы прописать это.

function myFunction() { 
this.value = 6 
} 
// Запись свойств прототипа функции myFunction 
console.log(myFunction.prototype)

В результате в консоли будет выведена информация, приведенная ниже:

Вывод 
{конструктор: ƒ}

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

const instance = new myFunction() 
console.log(instance.value)

В результате этого значения свойства value, которое вы впервые определили при установлении функции, будет предложено:

output 
6

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

const myArrowFunction = () => {} 
// Попытка сохранить в журнале свойство прототипа функции myArrowFunction 
console.log(myArrowFunction.prototype)

Результат будет:

output
не определен

Ключевое слово New недоступно, и вы не можете создать экземпляр из функции Аrrow, поскольку отсутствует атрибут прототипа

const arrowInstance = new myArrowFunction() 
console.log(arrowInstance)

Результат:

Output 
Uncaught TypeError: myArrowFunction не является конструктором

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

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

Неявный возврат

Обычная функция согласования в блоке, обозначенном фигурными скобками {}, который завершается, когда встречается кодет ключевое слово return. Такая реализация стрелочной функции выглядит следующим образом:

const sum = (c, d) => { 
return c + d 
}

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

const sum = (c, d) => c + d

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

При возврате объекта синтаксис требует, чтобы вы потеряли литерал объекта в круглых скобках. В случае возникновения скобки применяются как тело функции, и ее возвращаемое значение не вычисляется.

Появился следующий пример для наблюдений:

const sum = (c, d) => ({результат: c + d}) 
sum(3, 4)

Результат будет выглядеть следующим образом:

Output 
{результат: 7}

Круглые скобки вокруг одного параметра недопустимы

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

const square = (k) => k * k

Поэтому можно убрать круглые скобки вокруг аргумента, и функция все равно будет работать так, как нужно:

const square = k => k * k 
square (12)

Результат будет выглядеть следующим образом:

Output 
144

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

const welcome = () => 'Эй!' 
welcome()

Результаты вызова приветствие() возможно:

Output 
'Эй!'

Заключение

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

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


.

  • October 30, 2023