Как объявить функцию в javascript
Перейти к содержимому

Как объявить функцию в javascript

  • автор:

JavaScript: Функции

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

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

Объявление и вызов функции

Существует три способа объявления функции: Function Declaration, Function Expression и Named Function Expression.

Function Declaration (сокращённо FD) – это «классическое» объявление функции. В JavaScript функции объявляются с помощью литерала функции. Синтаксис объявления FD:

function идентификатор (параметры)

Литерал функции состоит из следующих четырёх частей:

  1. Ключевое слово function .
  2. Обязательный идентификатор, определяющий имя функции. В качестве имени функции обычно выбирают глагол, т. к. функция выполняет действие.
  3. Пара круглых скобок вокруг списка из нуля или более идентификаторов, разделяемых запятыми. Данные идентификаторы называются параметрами функции.
  4. Тело функции, состоящее из пары фигурных скобок, внутри которых располагаются инструкции. Тело функции может быть пустым, но фигурные скобки должны быть указаны всегда.

function sayHi()

Встречая ключевое слово function интерпретатор создаёт функцию и затем присваивает ссылку на неё переменной с именем sayHi (переменная с данным именем создаётся интерпретатором автоматически).

Обратившись к переменной sayHi можно увидеть, что в качестве значения там находится функция (на самом деле ссылка на неё):

alert(sayHi); // function sayHi()

Function Expression (сокращённо FE) – это объявление функции, которое является частью какого-либо выражения (например присваивания). Синтаксис объявления FE:

function (параметры)

var sayHi = function () < alert("Hello"); >;

Функцию FE иначе ещё называют » анонимной функцией «.

Named Function Expression (сокращённо NFE) – это объявление функции, которое является частью какого-либо выражения (например присваивания). Синтаксис объявления NFE:

function идентификатор (параметры)

var sayHi = function foo() < alert("Hello"); >;

Объявления FE и NFE обрабатываются интерпретатором точно так же, как и объявление FD: интерпретатор создаёт функцию и сохраняет ссылку на неё в переменной sayHi.

Программный код, расположенный в теле функции, выполняется не в момент объявления функции, а в момент её вызова. Для вызова функции используется оператор () (вызов функции):

function sayHi() < alert("Hello"); >var sayHi2 = function () < alert("Hello2"); >; var sayHi3 = function foo() < alert("Hello3"); >; sayHi(); // "Hello" sayHi2(); // "Hello2" sayHi3(); // "Hello3"

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

// Вызов функции до её объявления в коде верхнего уровня foo(); function foo() < alert("Вызов функции foo() в глобальной области видимости."); // Вызов функции до её объявления в области видимости функции bar(); function bar() < alert("Вызов функции bar() в области видимости функции."); >>

Функции, объявленные как FE или NFE, создаются в процессе выполнения кода, поэтому их можно вызывать только после того как они объявлены:

// sayHi(); // Ошибка. Функция sayHi ещё не существует var sayHi = function () < alert("Hello!"); >; sayHi();

Функции, объявленные внутри блока, находятся в блочной области видимости:

// foo(); // Ошибка. Функция не объявлена. < foo(); // 1 function foo() < console.log(1); >> foo(); // Ошибка. Функция не объявлена.

В отличие от FE, функция, объявленная как NFE, имеет возможность обращаться к себе по имени при рекурсивном вызове. Имя функции доступно только внутри самой функции:

(function sayHi(str) < if (str) < return; >sayHi("hi"); // Имя доступно внутри функции >)(); sayHi(); // Ошибка. Функция не объявлена

Функция обратного вызова

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

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

Ниже приведён пример функции, принимающей в качестве своего аргумента ссылку на другую функцию для её последующего вызова:

function foo(callback) < return callback(); >foo (function() < alert("Hello!"); >);

Этот пример наглядно демонстрирует принцип действия обратного вызова.

С этой темой смотрят:

  • Параметры и аргументы функции
  • arguments и this
  • Инструкция return
  • Рекурсия

Копирование материалов с данного сайта возможно только с разрешения администрации сайта
и при указании прямой активной ссылки на источник.
2011 – 2024 © puzzleweb.ru | razumnikum.ru

Функциональные выражения

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/function-expressions.

В JavaScript функция является значением, таким же как строка или число.

Как и любое значение, объявленную функцию можно вывести, вот так:

function sayHi() < alert( "Привет" ); >alert( sayHi ); // выведет код функции

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

Функцию можно скопировать в другую переменную:

function sayHi() < // (1) alert( "Привет" ); >var func = sayHi; // (2) func(); // Привет // (3) sayHi = null; sayHi(); // ошибка (4)
  1. Объявление (1) как бы говорит интерпретатору «создай функцию и помести её в переменную sayHi
  2. В строке (2) мы копируем функцию в новую переменную func . Ещё раз обратите внимание: после sayHi нет скобок. Если бы они были, то вызов var func = sayHi() записал бы в func результат работы sayHi() (кстати, чему он равен? правильно, undefined , ведь внутри sayHi нет return ).
  3. На момент (3) функцию можно вызывать и как sayHi() и как func()
  4. …Однако, в любой момент значение переменной можно поменять. При этом, если оно не функция, то вызов (4) выдаст ошибку.

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

Это действие можно запустить через скобки () , а можно и скопировать в другую переменную, как было продемонстрировано выше.

Объявление Function Expression

Существует альтернативный синтаксис для объявления функции, который ещё более наглядно показывает, что функция – это всего лишь разновидность значения переменной.

Он называется «Function Expression» (функциональное выражение) и выглядит так:

var f = function(параметры) < // тело функции >;
var sayHi = function(person) < alert( "Привет, " + person ); >; sayHi('Вася');

Сравнение с Function Declaration

«Классическое» объявление функции, о котором мы говорили до этого, вида function имя(параметры) <. >, называется в спецификации языка «Function Declaration».

  • Function Declaration – функция, объявленная в основном потоке кода.
  • Function Expression – объявление функции в контексте какого-либо выражения, например присваивания.

Несмотря на немного разный вид, по сути две эти записи делают одно и то же:

// Function Declaration function sum(a, b) < return a + b; >// Function Expression var sum = function(a, b)

Оба этих объявления говорят интерпретатору: «объяви переменную sum , создай функцию с указанными параметрами и кодом и сохрани её в sum «.

Основное отличие между ними: функции, объявленные как Function Declaration, создаются интерпретатором до выполнения кода.

Поэтому их можно вызвать до объявления, например:

sayHi("Вася"); // Привет, Вася function sayHi(name)

А если бы это было объявление Function Expression, то такой вызов бы не сработал:

sayHi("Вася"); // ошибка! var sayHi = function(name)

Это из-за того, что JavaScript перед запуском кода ищет в нём Function Declaration (их легко найти: они не являются частью выражений и начинаются со слова function ) и обрабатывает их.

А Function Expression создаются в процессе выполнения выражения, в котором созданы, в данном случае – функция будет создана при операции присваивания sayHi = function.

Как правило, возможность Function Declaration вызвать функцию до объявления – это удобно, так как даёт больше свободы в том, как организовать свой код.

Можно расположить функции внизу, а их вызов – сверху или наоборот.

Условное объявление функции

В некоторых случаях «дополнительное удобство» Function Declaration может сослужить плохую службу.

Например, попробуем, в зависимости от условия, объявить функцию sayHi по-разному:

var age = +prompt("Сколько вам лет?", 20); if (age >= 18) < function sayHi() < alert( 'Прошу вас!' ); >> else < function sayHi() < alert( 'До 18 нельзя' ); >> sayHi();

Function Declaration при use strict видны только внутри блока, в котором объявлены. Так как код в учебнике выполняется в режиме use strict , то будет ошибка.

А что, если использовать Function Expression?

var age = prompt('Сколько вам лет?'); var sayHi; if (age >= 18) < sayHi = function() < alert( 'Прошу Вас!' ); >> else < sayHi = function() < alert( 'До 18 нельзя' ); >> sayHi();
var age = prompt('Сколько вам лет?'); var sayHi = (age >= 18) ? function() < alert('Прошу Вас!'); >: function() < alert('До 18 нельзя'); >; sayHi();

Оба этих варианта работают правильно, поскольку, в зависимости от условия, создаётся именно та функция, которая нужна.

Анонимные функции

Взглянем ещё на один пример – функцию ask(question, yes, no) с тремя параметрами:

question Строка-вопрос yes Функция no Функция

Она выводит вопрос на подтверждение question и, в зависимости от согласия пользователя, вызывает функцию yes() или no() :

function ask(question, yes, no) < if (confirm(question)) yes() else no(); >function showOk() < alert( "Вы согласились." ); >function showCancel() < alert( "Вы отменили выполнение." ); >// использование ask("Вы согласны?", showOk, showCancel);

Какой-то очень простой код, не правда ли? Зачем, вообще, может понадобиться такая ask ?

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

Здесь же обратим внимание на то, что то же самое можно написать более коротко:

function ask(question, yes, no) < if (confirm(question)) yes() else no(); >ask( "Вы согласны?", function() < alert("Вы согласились."); >, function() < alert("Вы отменили выполнение."); >);

Здесь функции объявлены прямо внутри вызова ask(. ) , даже без присвоения им имени.

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

Действительно, зачем нам записывать функцию в переменную, если мы не собираемся вызывать её ещё раз? Можно просто объявить непосредственно там, где функция нужна.

Такого рода код возникает естественно, он соответствует «духу» JavaScript.

new Function

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

Он позволяет создавать функцию полностью «на лету» из строки, вот так:

var sum = new Function('a,b', ' return a+b; '); var result = sum(1, 2); alert( result ); // 3

То есть, функция создаётся вызовом new Function(params, code) :

params Параметры функции через запятую в виде строки. code Код функции в виде строки.

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

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

Итого

Функции в JavaScript являются значениями. Их можно присваивать, передавать, создавать в любом месте кода.

  • Если функция объявлена в основном потоке кода, то это Function Declaration.
  • Если функция создана как часть выражения, то это Function Expression.

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

Function Declaration Function Expression
Время создания До выполнения первой строчки кода. Когда управление достигает строки с функцией.
Можно вызвать до объявления Да (т.к. создаётся заранее) Нет
Условное объявление в if Не работает Работает

Иногда в коде начинающих разработчиков можно увидеть много Function Expression. Почему-то, видимо, не очень понимая происходящее, функции решают создавать как var func = function() , но в большинстве случаев обычное объявление функции – лучше.

Если нет явной причины использовать Function Expression – предпочитайте Function Declaration.

Сравните по читаемости:

// Function Expression var f = function() < . >// Function Declaration function f()

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

Используйте Function Expression только там, где это действительно нужно и удобно.

Синтаксис «new Function»

Существует ещё один вариант объявления функции. Он используется крайне редко, но иногда другого решения не найти.

Синтаксис

Синтаксис для объявления функции:

let func = new Function([arg1, arg2, . argN], functionBody);

Функция создаётся с заданными аргументами arg1. argN и телом functionBody .

Это проще понять на конкретном примере. Здесь объявлена функция с двумя аргументами:

let sum = new Function('a', 'b', 'return a + b'); alert( sum(1, 2) ); // 3

А вот функция без аргументов, в этом случае достаточно указать только тело:

let sayHi = new Function('alert("Hello")'); sayHi(); // Hello

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

Все предыдущие объявления требовали от нас, программистов, писать объявление функции в скрипте.

Но new Function позволяет превратить любую строку в функцию. Например, можно получить новую функцию с сервера и затем выполнить её:

let str = . код, полученный с сервера динамически . let func = new Function(str); func();

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

Замыкание

Обычно функция запоминает, где родилась, в специальном свойстве [[Environment]] . Это ссылка на лексическое окружение (Lexical Environment), в котором она создана (мы разбирали это в главе Область видимости переменных, замыкание).

Но когда функция создаётся с использованием new Function , в её [[Environment]] записывается ссылка не на внешнее лексическое окружение, в котором она была создана, а на глобальное. Поэтому такая функция имеет доступ только к глобальным переменным.

function getFunc() < let value = "test"; let func = new Function('alert(value)'); return func; >getFunc()(); // ошибка: value не определено

Сравним это с обычным объявлением:

function getFunc() < let value = "test"; let func = function() < alert(value); >; return func; > getFunc()(); // "test", из лексического окружения функции getFunc

Эта особенность new Function выглядит странно, но оказывается очень полезной на практике.

Представьте, что нужно создать функцию из строки. Код этой функции неизвестен во время написания скрипта (поэтому не используем обычные функции), а будет определён только в процессе выполнения. Мы можем получить код с сервера или с другого ресурса.

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

Что если бы она имела доступ к внешним переменным?

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

Например, если в функции объявляется переменная let userName , то минификатор изменяет её на let a (или другую букву, если она не занята) и изменяет её везде. Обычно так делать безопасно, потому что переменная является локальной, и никто снаружи не имеет к ней доступ. И внутри функции минификатор заменяет каждое её упоминание. Минификаторы достаточно умные. Они не просто осуществляют «тупой» поиск-замену, они анализируют структуру кода, и поэтому ничего не ломается.

Так что если бы даже new Function и имела доступ к внешним переменным, она не смогла бы найти переименованную userName .

Если бы new Function имела доступ к внешним переменным, при этом были бы проблемы с минификаторами.

Кроме того, такой код был бы архитектурно хуже и более подвержен ошибкам.

Чтобы передать что-то в функцию, созданную как new Function , можно использовать её аргументы.

Итого

let func = new Function ([arg1, arg2, . argN], functionBody);

По историческим причинам аргументы также могут быть объявлены через запятую в одной строке.

Эти 3 объявления ниже эквивалентны:

new Function('a', 'b', 'return a + b'); // стандартный синтаксис new Function('a,b', 'return a + b'); // через запятую в одной строке new Function('a , b', 'return a + b'); // через запятую с пробелами в одной строке

Функции, объявленные через new Function , имеют [[Environment]] , ссылающийся на глобальное лексическое окружение, а не на родительское. Поэтому они не могут использовать внешние локальные переменные. Но это очень хорошо, потому что страхует нас от ошибок. Переданные явно параметры – гораздо лучшее архитектурное решение, которое не вызывает проблем у минификаторов.

Function Expression

Функция в JavaScript – это не магическая языковая структура, а особого типа значение.

Синтаксис, который мы использовали до этого, называется Function Declaration (Объявление Функции):

function sayHi()

Существует ещё один синтаксис создания функций, который называется Function Expression (Функциональное Выражение).

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

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

let sayHi = function() < alert( "Привет" ); >;

Здесь мы можем видеть переменную sayHi , получающую значение, новую функцию, созданную как function() < alert("Привет"); >.

Поскольку создание функции происходит в контексте выражения присваивания (с правой стороны от = ), это Function Expression.

Обратите внимание, что после ключевого слова function нет имени. Для Function Expression допускается его отсутствие.

Здесь мы сразу присваиваем её переменной, так что смысл этих примеров кода один и тот же: «создать функцию и поместить её в переменную sayHi «.

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

Функция – это значение

Давайте повторим: независимо от того, как создаётся функция – она является значением. В обоих приведённых выше примерах функция хранится в переменной sayHi .

Мы даже можем вывести это значение с помощью alert :

function sayHi() < alert( "Привет" ); >alert( sayHi ); // выведет код функции

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

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

Конечно, функция – это особое значение, в том смысле, что мы можем вызвать её как sayHi() .

Но всё же это значение. Поэтому мы можем работать с ней так же, как и с другими видами значений.

Мы можем скопировать функцию в другую переменную:

function sayHi() < // (1) создаём alert( "Привет" ); >let func = sayHi; // (2) копируем func(); // Привет // (3) вызываем копию (работает)! sayHi(); // Привет // эта тоже все ещё работает (почему бы и нет)

Давайте подробно разберём всё, что тут произошло:

  1. Объявление Function Declaration (1) создаёт функцию и помещает её в переменную с именем sayHi .
  2. В строке (2) мы скопировали её значение в переменную func . Обратите внимание (ещё раз): нет круглых скобок после sayHi . Если бы они были, то выражение func = sayHi() записало бы результат вызова sayHi() в переменную func , а не саму функцию sayHi .
  3. Теперь функция может вызываться как sayHi() , так и func() .

Мы также могли бы использовать Function Expression для объявления sayHi в первой строке:

let sayHi = function() < // (1) создаём alert( "Привет" ); >; let func = sayHi; // . 

Всё будет работать так же.

Зачем нужна точка с запятой в конце?

У вас мог возникнуть вопрос: Почему в Function Expression ставится точка с запятой ; на конце, а в Function Declaration нет:

function sayHi() < // . >let sayHi = function() < // . >;

Ответ прост: Function Expression создаётся здесь как function(. ) <. >внутри выражения присваивания: let sayHi = …; . Точку с запятой ; рекомендуется ставить в конце выражения, она не является частью синтаксиса функции.

Точка с запятой нужна там для более простого присваивания, такого как let sayHi = 5; , а также для присваивания функции.

Функции-«колбэки»

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

Давайте напишем функцию ask(question, yes, no) с тремя параметрами:

question Текст вопроса yes Функция, которая будет вызываться, если ответ будет «Yes» no Функция, которая будет вызываться, если ответ будет «No»

Наша функция должна задать вопрос question и, в зависимости от того, как ответит пользователь, вызвать yes() или no() :

function ask(question, yes, no) < if (confirm(question)) yes() else no(); >function showOk() < alert( "Вы согласны." ); >function showCancel() < alert( "Вы отменили выполнение." ); >// использование: функции showOk, showCancel передаются в качестве аргументов ask ask("Вы согласны?", showOk, showCancel);

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

Аргументы showOk и showCancel функции ask называются функциями-колбэками или просто колбэками.

Ключевая идея в том, что мы передаём функцию и ожидаем, что она вызовется обратно (от англ. «call back» – обратный вызов) когда-нибудь позже, если это будет необходимо. В нашем случае, showOk становится колбэком для ответа «yes», а showCancel – для ответа «no».

Мы можем переписать этот пример значительно короче, используя Function Expression:

function ask(question, yes, no) < if (confirm(question)) yes() else no(); >ask( "Вы согласны?", function() < alert("Вы согласились."); >, function() < alert("Вы отменили выполнение."); >);

Здесь функции объявляются прямо внутри вызова ask(. ) . У них нет имён, поэтому они называются анонимными. Такие функции недоступны снаружи ask (потому что они не присвоены переменным), но это как раз то, что нам нужно.

Подобный код, появившийся в нашем скрипте выглядит очень естественно, в духе JavaScript.

Функция – это значение, представляющее «действие»

Обычные значения, такие как строки или числа представляют собой данные.

Функции, с другой стороны, можно воспринимать как действия.

Мы можем передавать их из переменной в переменную и запускать, когда захотим.

Function Expression в сравнении с Function Declaration

Давайте разберём ключевые отличия Function Declaration от Function Expression.

Во-первых, синтаксис: как отличить их друг от друга в коде.

    Function Declaration: функция объявляется отдельной конструкцией «function…» в основном потоке кода.

// Function Declaration function sum(a, b)
// Function Expression let sum = function(a, b) < return a + b; >;

Более тонкое отличие состоит в том, когда создаётся функция движком JavaScript.

Function Expression создаётся, когда выполнение доходит до него, и затем уже может использоваться.

После того, как поток выполнения достигнет правой части выражения присваивания let sum = function… – с этого момента, функция считается созданной и может быть использована (присвоена переменной, вызвана и т.д. ).

С Function Declaration всё иначе.

Function Declaration может быть вызвана раньше, чем она объявлена.

Другими словами, когда движок JavaScript готовится выполнять скрипт или блок кода, прежде всего он ищет в нём Function Declaration и создаёт все такие функции. Можно считать этот процесс «стадией инициализации».

И только после того, как все объявления Function Declaration будут обработаны, продолжится выполнение.

В результате функции, созданные как Function Declaration, могут быть вызваны раньше своих определений.

Например, так будет работать:

sayHi("Вася"); // Привет, Вася function sayHi(name) < alert( `Привет, $` ); >

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

…Если бы это было Function Expression, то такой код вызвал бы ошибку:

sayHi("Вася"); // ошибка! let sayHi = function(name) < // (*) магии больше нет alert( `Привет, $` ); >;

Функции, объявленные при помощи Function Expression, создаются тогда, когда выполнение доходит до них. Это случится только на строке, помеченной звёздочкой (*) . Слишком поздно.

Ещё одна важная особенность Function Declaration заключается в их блочной области видимости.

В строгом режиме, когда Function Declaration находится в блоке <. >, функция доступна везде внутри блока. Но не снаружи него.

Для примера давайте представим, что нам нужно объявить функцию welcome() в зависимости от значения переменной age , которое мы получим во время выполнения кода. И затем запланируем использовать её когда-нибудь в будущем.

Если мы попробуем использовать Function Declaration, это не заработает так, как задумывалось:

let age = prompt("Сколько Вам лет?", 18); // в зависимости от условия объявляем функцию if (age < 18) < function welcome() < alert("Привет!"); >> else < function welcome() < alert("Здравствуйте!"); >> // . не работает welcome(); // Error: welcome is not defined

Это произошло, так как объявление Function Declaration видимо только внутри блока кода, в котором располагается.

Вот ещё один пример:

let age = 16; // возьмём для примера 16 if (age < 18) < welcome(); // \ (выполнится) // | function welcome() < // | alert("Привет!"); // | Function Declaration доступно >// | во всём блоке кода, в котором объявлено // | welcome(); // / (выполнится) > else < function welcome() < alert("Здравствуйте!"); >> // здесь фигурная скобка закрывается, // поэтому Function Declaration, созданные внутри блока кода выше -- недоступны отсюда. welcome(); // Ошибка: welcome is not defined

Что можно сделать, чтобы welcome была видима снаружи if ?

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

Такой код заработает, как ожидалось:

let age = prompt("Сколько Вам лет?", 18); let welcome; if (age < 18) < welcome = function() < alert("Привет!"); >; > else < welcome = function() < alert("Здравствуйте!"); >; > welcome(); // теперь всё в порядке

Или мы могли бы упростить это ещё сильнее, используя условный оператор ? :

let age = prompt("Сколько Вам лет?", 18); let welcome = (age < 18) ? function() < alert("Привет!"); >: function() < alert("Здравствуйте!"); >; welcome(); // теперь всё в порядке

Когда использовать Function Declaration, а когда Function Expression?

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

Также функции вида function f(…) чуть более заметны в коде, чем let f = function(…) . Function Declaration легче «ловятся глазами».

…Но если Function Declaration нам не подходит по какой-то причине, или нам нужно условное объявление (мы рассмотрели это в примере выше), то следует использовать Function Expression.

Итого

  • Функции – это значения. Они могут быть присвоены, скопированы или объявлены в любом месте кода.
  • Если функция объявлена как отдельная инструкция в основном потоке кода, то это “Function Declaration”.
  • Если функция была создана как часть выражения, то это “Function Expression”.
  • Function Declaration обрабатываются перед выполнением блока кода. Они видны во всём блоке.
  • Функции, объявленные при помощи Function Expression, создаются только когда поток выполнения достигает их.

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

Исходя из этого, мы должны использовать Function Expression только тогда, когда Function Declaration не подходит для нашей задачи. Мы рассмотрели несколько таких примеров в этой главе, и увидим ещё больше в будущем.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *