какие функции выполняет javascript
JavaScript для чайников. Всё что вы хотели знать о функциях но боялись спросить
Как-то незаметно для себя, я решил отойти от возни с классами и паттернами, и разобраться с самыми обычными Js функциями. Думал, что будет достаточно скучно, но ошибся — оказалось очень даже интересно.
В этой статье я расскажу об особенностях объявления функций, и некоторых полезных паттернах (кхе-хе, да, они есть и тут)
1. Объявление функции
Если не обращать внимание на всякие извращения, то объявить функцию можно всего двумя способами:
Разница между ними кажется небольшой, но это только кажется.
Что будет если выполнить этот код?
правильно — в консоли появится сначала текст с названием примера, а потом единичка, потому что все именованные функции переносятся в начало области видимости, и вызывать их можно когда угодно.
Усложняем задачу
Но нас ведь так просто не запутать. Функции переносятся в начало ровно в том порядке, в котором они были созданы, то есть в консоли будет 2.
Ладно, а так?
Ответ: а тут правила другие — это вообще не заработает, потому что значение переменной на момент вызова — undefined.
А если так?
Ну тут уже все ясно, да — на момент вызова е содержит в себе первую функцию, так что в консоли будет единичка.
А теперь настало время для самого сложного вопроса *барабанная дробь*
правильный ответ: два раза единичка. После своего объявления, переменные перекрывают функции.
Всегда.
Immediate functions
За этим названием скрываются «одноразовые» функции — они не имеют имени, и выполняются сразу после своего объявления.
Зачем это нужно? По большей части за тем, чтобы не засорять глобальное пространство имен. Например, если надо проинициализировать что-нибудь, и при инициализации нам потребуется парочка переменных которые потом вообще совсем не нужны.
Объявить такую функцию можно двумя, по сути, эквивалентными способами.
Отличий между ними нет никаких.
Init time branching
Иногда случается, что значение функции зависит от какого-нибудь значения, которое после инциализации не меняется. ну что-нибудь вроде этого:
Все здорово, кроме того, что каждый раз при вызове мы делаем ставшую уже абсолютно ненужной проверку. Переписать функцию можно так:
Как мог заметить внимательный читатель, здесь используется ещё и immidiate function. Теперь проверка выполняется ровно один раз.
Self defining function
Иногда бывает так, что при первом вызове функции нужно выполнить какие-нибудь дополнительные действия. Реализовать это можно следующим образом:
Такой прием помогает сэкономить одну переменную за пределами функции, по которой мы бы проверяли вызывалась функция или нет.
Currying
С помощью этого приема можно создать частный вариант какой-нибудь довольно общей функции. Реализация выглядит так:
Пока конечно нифига непонятно, но это нормально. Сейчас все объясню.
Допустим у нас есть функция которая печатает сообщение.
Но в данном модуле проекта в качестве значения author всегда используют me, так что нам очень желательна более частная её версия принимающая только строчку с сообщением, а автора вписывающая сама.
И теперь она у нас есть.
UPD. Дополнение к статье от одного очень хорошего человека с ником jamayka
Объявление рекурсивных функций
Например, у нас есть тупо факториал, который используется в куче кода:
Потом по каким-то причинам нам нужно
В итоге получается, что и вызовы factorial(5) и realFactorial(5) вываливают ошибку. Это получается, т.к. рекурсивный вызов factorial использует переменную из родительской области видимости, а там она переопределяется. В этом случае надо определять функцию так:
Ну или чтобы не путаться:
Вроде бы всё — как всегда, исходники примеров скачать можно тут
Форум
Справочник
Функции
В этой статье описаны функции Javascript на уровне языка: создание, параметры, приемы работы, замыкания и многое другое.
Создание функций
В javascript функции являются полноценными объектами встроенного класса Function. Именно поэтому их можно присваивать переменным, передавать и, конечно, у них есть свойства:
Свойства функции доступны и внутри функции, так что их можно использовать как статические переменные.
В примере нельзя было сделать присвоение:
Области видимости
Каждая функция, точнее даже каждый запуск функции задает свою индивидуальную область видимости.
Параметры функции
Функции можно запускать с любым числом параметров.
Третий запуск задает несколько дополнительных аргументов. В функции не предусмотрена работа с дополнительными аргументами, поэтому они просто игнорируются.
Работа с неопределенным числом параметров
Если все же хочется воспользоваться этими методами, например, чтобы вызвать другую функцию с теми же аргументами, но кроме первого, можно создать из arguments настоящий массив:
Вызвать функцию для массива аргументов можно при помощи apply :
Пример передачи функции по ссылке
Функцию легко можно передавать в качестве аргумента другой функции.
Или можно создать анонимную функцию непосредственно в вызове map :
Сворачивание параметров в объект
Бывают функции, аргументы которых сильно варьируются.
Вызов с необязательными параметрами приходится делать так:
Чтобы избежать лишних null и сделать код более понятным, используют нечто вроде «keyword arguments», существующих в Python и Ruby. Для этого много параметров пакуют в единый объект:
Вызов теперь делается гораздо проще:
Кроме того, с объектом можно удобнее делать последовательности вызовов вроде:
Конечно мне всё описанное в статье уже известно, но материал очень полезный.
Жаль, что в то время, когда я только начинал изучать программирование и JavaScript, не было таких статей.
Да, статьи у тебя, Илья, как всегда, полезны. Доходчиво написано, особенно для новичков.
Есть маленькое уточнение:
не каждая именованная функция является declaration’ом:
Для новичков.
Вот я новичок. И я ничерта не понял) После второго абзаца мозг расплавился.
Хотя я пытался выяснить простую вещь: почему в функцию передается число и не передается текст? Но этого тут я так и не нашел =\
В функцию в качестве аргумента элементарно передать как числовую, так и строковую переменную.
Спасибо огромное! Очень долго искал вот это для своей JS библиотеки:
Поддержу, отличный метод
А как все таки задавать значения параметров по умолчанию?
Только уже в самом теле функции?
Да, только в теле функции
Блин, а я как не разбиралась в Яве, так и не разбираюсь. Надо учиться
или последнее, которое приводится к false
Никак. Элементарные значения не передаются по ссылке, только объекты, к которым также относятся массивы, даты и т.п.
Здесь javascript ведет себя так же, как, например, java/php5
А вот и неправда, можно привести их к object и передать в функцию, тогда они будут переданы по ссылке
Я правильно понимаю?
Да, Ты понимаешь правильно
пиши так:
function myFunc(s)
<
if (typeof s == «undefined») s = «default value for s»;
alert(s);
>;
Не понятно про имена функций при вызове по ссылке. Мы можем сослатся на функцию вот так:
Тоесть мы переменную myFunc фактически приравниваем к функции.
Но мочему тогда нельзя сделать вот так?
Привет. Присвоение значения переменной надо делать без кавычек:
var someVar = myFunc;
Спасибо за ответ, но. 🙂
Суть именно в том, что в кавычках вычесляется имя функции, которую нужно запустить. Кавычки тут не зря. К примеру:
Только если записывать ф-ию в хеш (или объявлять ее глобально, что почти тоже самое: она попадет в объект window).
Руководство по JavaScript, часть 4: функции
Сегодня публикуем четвёртую часть перевода руководства по JavaScript, которая посвящена функциям.
Функции в JavaScript
Поговорим о функциях в JavaScript, сделаем их общий обзор и рассмотрим подробности о них, знание которых позволит вам эффективно ими пользоваться.
Функция — это самостоятельный блок кода, который можно, один раз объявив, вызывать столько раз, сколько нужно. Функция может, хотя это и необязательно, принимать параметры. Функции возвращают единственное значение.
Кроме того, функции в JavaScript называют «функциями первого класса» так как их можно назначать переменным, их можно передавать другим функциям в качестве аргументов, их можно возвращать из других функций.
Сначала рассмотрим особенности работы с функциями и соответствующие синтаксические конструкции, которые существовали в языке до появления стандарта ES6 и актуальны до сих пор.
Вот как выглядит объявление функции (function declaration).
В наши дни такие функции называют «обычными», отличая их от «стрелочных» функций, которые появились в ES6.
Функцию можно назначить переменной или константе. Такая конструкция называется функциональным выражением (function expression).
Можно заметить, что в вышеприведённом примере функция назначена константе, но сама она имени не имеет. Такие функции называют анонимными. Подобным функциям можно назначать имена. В таком случае речь идёт об именованном функциональном выражении (named function expression).
Использование таких выражений повышает удобство отладки (в сообщениях об ошибках, где проводится трассировка стека, видно имя функции). Имя функции в функциональном выражении может понадобиться и для того, чтобы функция могла бы сама себя вызывать, без чего не обойтись при реализации рекурсивных алгоритмов.
В стандарте ES6 появились стрелочные функции (arrow function), которые особенно удобно использовать в виде так называемых «встроенных функций» (inline function) — в роли аргументов, передаваемых другим функциям (коллбэков).
Стрелочные функции, помимо того, что структуры, используемые для их объявления, получаются более компактными, чем при использовании обычных функций, отличаются от них некоторыми важными особенностями, о которых мы поговорим ниже.
Параметры функций
Параметры представляют собой переменные, которые задаются на этапе объявления функции и будут содержать передаваемые ей значения (эти значения называют аргументами). Функции в JavaScript могут либо не иметь параметров, либо иметь один или несколько параметров.
Здесь показано несколько примеров стрелочных функций.
Начиная со стандарта ES6 у функций могут быть так называемые «параметры по умолчанию» (default parameters).
Они представляют собой стандартные значения, задаваемые параметрам функций в том случае, если при её вызове значения некоторых параметров не задаются. Например, функцию, показанную выше, можно вызвать как с передачей ей всех двух принимаемых ей параметров, так и другими способами.
В ES8 появилась возможность ставить запятую после последнего аргумента функции (это называется trailing comma). Эта возможность позволяет повысить удобство редактирования кода при использовании систем контроля версий в ходе разработки программ. Подробности об этом можно почитать здесь и здесь.
Передаваемые функциям аргументы можно представлять в виде массивов. Для того чтобы разобрать эти аргументы можно воспользоваться оператором, который выглядит как три точки (это — так называемый «оператор расширения» или «оператор spread»). Вот как это выглядит.
Если функции нужно принимать много параметров, то запомнить порядок их следования может быть непросто. В таких случаях используются объекты с параметрами и возможности по деструктурированию объектов ES6.
Этот приём позволяет, описывая параметры в виде свойств объекта и передавая функции объект, получить в функции доступ к параметрам по их именам без использования дополнительных конструкций. Подробнее об этом приёме можно почитать здесь.
Значения, возвращаемые из функций
Если после ключевого слова return указать некое значение, то это значение возвращается в место вызова функции в качестве результата выполнения этой функции.
Из функции можно возвращать лишь одно значение. Для того чтобы получить возможность возврата нескольких значений, возвращать их можно либо в виде объекта, используя объектный литерал, либо в виде массива, а при вызове функции применять конструкцию деструктурирующего присваивания. Имена параметров при этом сохраняются. При этом, если нужно работать с объектом или массивом, возвращённым из функции, именно в виде объекта или массива, можно обойтись без деструктурирующего присваивания.
Конструкцию const [ name, age ] = doSomething() можно прочитать следующим образом: «объявить константы name и age и присвоить им значения элементов массива, который возвратит функция».
Вот как то же самое выглядит с использованием объекта.
Вложенные функции
Функции можно объявлять внутри других функций.
Область видимости вложенной функции ограничена внешней по отношению к ней функцией, её нельзя вызвать извне.
Методы объектов
Когда функции используются в качестве свойств объектов, такие функции называют методами объектов.
Ключевое слово this
Как видно, вызов метода start() приводит ко вполне ожидаемому результату, а вот метод stop() явно работает неправильно.
Вот как выглядит выполнение такого кода в консоли браузера.
Особенности ключевого слова this в обычных и стрелочных функциях
Всё это означает, что стрелочные функции не подходят на роль методов объектов и конструкторов (если попытаться использовать стрелочную функцию в роли конструктора — будет выдана ошибка TypeError ).
Немедленно вызываемые функциональные выражения
Немедленно вызываемое функциональное выражение (Immediately Invoked Function Expression, IIFE) — это функция, которая автоматически вызывается сразу после её объявления.
Точка с запятой перед IIFE необязательна, но её использование позволяет застраховаться от ошибок, связанных с автоматической расстановкой точек с запятой.
Поднятие функций
Если переместить вызов функции так, чтобы он шёл после её объявления, ничего не изменится.
Если же в похожей ситуации воспользоваться функциональным выражением, то похожий код выдаст ошибку.
Стрелочные функции
Сейчас мы подробнее поговорим о стрелочных функциях, с которыми мы уже встречались. Их можно считать одним из наиболее значительных новшеств стандарта ES6, они отличаются от обычных функций не только внешним видом, но и особенностями поведения. В наши дни они используются чрезвычайно широко. Пожалуй, нет ни одного современного проекта, где они не использовались бы в подавляющем большинстве случаев. Можно сказать, что их появление навсегда изменило и внешний вид JS-кода и особенности его работы.
С чисто внешней точки зрения синтаксис объявления стрелочных функций оказывается компактнее синтаксиса обычных функций. Вот объявление обычной функции.
Вот объявление стрелочной функции, которое, в целом, если не учитывать особенности стрелочных функций, аналогично предыдущему.
Как видите, параметры стрелочных функций, как и в случае с обычными функциями, описывают в скобках. При этом, если такая функция принимает всего один параметр, его можно указать без скобок. Например, вот функция, которая возвращает результат деления переданного ей числа на 2.
В результате оказывается, что стрелочные функции очень удобно использовать в ситуациях, в которых нужны маленькие функции.
▍Неявный возврат результатов работы функции
Мы уже касались этой особенности стрелочных функций, но она настолько важна, что её следует обсудить подробнее. Речь идёт о том, что однострочные стрелочные функции поддерживают неявный возврат результатов своей работы. Пример возврата примитивного значения из однострочной стрелочной функции мы уже видели. Как быть, если такая функция должна возвратить объект? В таком случае фигурные скобки объектного литерала могут запутать систему, поэтому в теле функции используются круглые скобки.
▍Ключевое слово this и стрелочные функции
Как мы уже видели, при использовании ключевого слова this в методе объекта, представленного обычной функцией, this указывает на объект, которому принадлежит метод. В таком случае говорят о привязке ключевого слова this к значению, представляющему собой контекст выполнения функции. В частности, если функция вызвана в виде метода объекта, то ключевое слово this привязано к этому объекту.
В случае же со стрелочными функциями оказывается так, что в них привязка this не выполняется, они пользуются ключевым словом this из содержащих их областей видимости. В результате их не рекомендуется использовать в качестве методов объектов.
Замыкания
Замыкания — это важная концепция в JavaScript. Фактически, если вы писали JS-функции, то вы пользовались и замыканиями. Замыкания применяются в некоторых паттернах проектирования — в том случае, если нужно организовать строгий контроль доступа к неким данным или функциям.
Когда функция вызывается, у неё есть доступ ко всему тому, что находится во внешней по отношению к ней области видимости. Но к тому, что объявлено внутри функции, извне доступа нет. То есть, если в функции была объявлена некая переменная (или другая функция), они недоступны внешнему коду ни во время выполнения функции, ни после завершения её работы. Однако если из функции возвратить другую функцию, то эта новая функция будет иметь доступ ко всему тому, что было объявлено в исходной функции. При этом всё это будет скрыто от внешнего кода в замыкании.
Рассмотрим пример. Вот функция, которая принимает имя собаки, после чего выводит его в консоль.
Значение, возвращаемое этой функцией нас пока не интересует, текст выводится в консоль с помощью IIFE, что в данном случае особой роли не играет, однако, это поможет нам увидеть связь между этой функцией и её вариантом, в котором, вместо вызова функции, которая выводит текст в консоль, мы эту функцию из переписанной функции bark() возвратим.
Результат работы код в двух случаях оказывается одинаковым. Но во втором случае то, что было передано исходной функции при её вызове (имя собаки, Roger ), хранится в замыкании, после чего используется другой функцией, возвращённой из исходной.
Проведём ещё один эксперимент — создадим, пользуясь исходной функцией, две новых, для разных собак.
Этот код выведет следующее.
Итоги
Уважаемые читатели! Как вы относитесь к стрелочным функциям в JavaScript?
Подробно о функциях JavaScript
Функции JavaScript определяются при помощи ключевого слова function.
Вы можете использовать либо декларацию функции, либо функцию-выражение.
Декларация функции
Ранее в этом учебнике мы узнали, что декларация функции имеет следующий синтаксис:
Декларированные функции выполняются не сразу. Они имеют статус «отложенного использования» и выполняются только тогда, когда к ним обратятся (вызовут).
Внимание! Точка с запятой используется для разделения выполняемых выражений JavaScript. Так как декларация функции не является выполняемым выражением, в конце нее обычно не ставят точку с запятой.
Функции-выражения
Также функции JavaScript могут определяться с использованием выражения.
Функции-выражения могут храниться в переменных:
После того как функция-выражение сохранена в переменной, эта переменная может использоваться как функция:
На самом деле функция в предыдущем примере является анонимной (функция без имени).
Функциям, сохраненным в переменных, не нужны имена. Они вызываются при помощи имени переменной.
Внимание! В конце функции из предыдущего примера стоит точка с запятой, так как она часть выполняемого выражения.
Конструктор Function()
Как вы видели в предыдущих примерах, функции JavaScript определяются при помощи ключевого слова function.
Однако, кроме этого функции также могут определяться при помощи встроенной функции конструктора Function().
Тем не менее, на самом деле вам не нужно использовать функцию конструктора.
Предыдущий пример аналогичен следующему коду:
В большинстве случаев в JavaScript можно избежать использование ключевого слова new.
Поднятие функций
Ранее в этом учебнике вы уже познакомились с таким понятием, как «поднятие» переменных. (Глава Поднятие переменных в Javascript)
«Поднятие» — это такое поведение JavaScript, при котором декларации перемещаются (поднимаются) в начало текущей области видимости.
Поднятие применяется к декларациям переменных и функций.
Благодаря этому функции JavaScript можно вызывать до того, как они будут декларированы:
Внимание! Функции, декларированные как выражения, не поднимаются.
Самовызываемые функции
Функции-выражения могут быть «самовызываемыми».
Самовызываемые выражения вызываются (начинают работать) автоматически без специального вызова.
Функция-выражение будет выполняться автоматически, если после выражения стоят круглые скобки ().
При этом декларация функции не может быть самовызываемой. Чтобы указать, что это функция-выражение, необходимо заключить ее в круглые скобки:
Функция в предыдущем примере это анонимная самовызываемая функция.
Функции могут использоваться как значения
Функции JavaScript могут использоваться как значения:
Функции JavaScript могут использоваться в выражениях:
Функции — это объекты
Оператор typeof в JavaScript возвращает для функций тип «function». Однако лучше всего функции JavaScript можно описать как объекты.
У функций JavaScript есть свойства и методы.
Свойство arguments.length возвращает количество параметров, полученных при вызове функции:
Метод toString() возвращает функцию как строку:
Функция, определенная как свойство объекта, называется методом объекта.
Функция, предназначенная для создания новых объектов, называется конструктором объекта.
«Стрелочные» функции
«Стрелочные» функции предоставляют короткую запись для выражений-функций.
При этом в выражении-функции не нужно использовать ключевые слова function, return и фигурные скобки:
У стрелочных функций нет своего значения this. И они не подходят для определения методов объектов.
Стрелочные функции не поднимаются. Они должны определяться до их использования.
Для декларации стрелочных функций использовать ключевое слова const безопаснее ключевого слова var, потому что по своей сути функция — это константное значение.
Не писать ключевое слово return и фигурные скобки можно только, если функция состоит из одного выражения.
Хорошей привычкой будет писать их всегда:
Стрелочные функции не поддерживаются в IE11 и более ранних версиях IE.
Основы JavaScript: функции
Sep 18, 2019 · 6 min read
Функции могут считаться как одними из ключевых строительных блоков JavaScript программ. Функция — это просто набор команд, разработанных для выполнения определенной задачи, которая исполняется при вызове.
Определение функции
Посмотрим на примере:
Функциональное выражение
Есть е щ е один способ определения функции, а именно, функциональное выражение. Такие типы функций могут быть анонимными. Нет необходимости давать им название.
Например, предыдущую функцию multiply можно записать следующим образом:
Также распространённым случаем является передача функционального выражения в качестве аргумента другой функции.
Еще мы можем определить функцию, основанную на условии. Например, следующая функция addItem сработает, только если num будет равно 1:
Вызов функции
При определении функции все, что нам необходимо сделать, это дать ей название и передать инструкции, которые исполнятся при ее вызове.
Для того, чтобы вызвать нашу функцию multiply необходимо записать:
Функция должна быть в области видимости при вызове, однако определение функции может быть поднято (располагаться ниже вызова в коде), например:
Область видимости функции — это либо та функция, в которой она определена, либо вся программа, если определение функции находится на глобальном уровне.
Обратите внимание: это работает только со стандартной функцией, а не с функциональным выражением.
Область видимости функции
Когда переменные определяются внутри функции, к ним нельзя получить доступ извне, так как это будет вне ее области видимости. Однако у функции есть доступ ко всем переменным и функциям внутри области видимости, в которой она определена. Так, функция, определенная в глобальной области видимости, имеет доступ ко всем переменным в этой области. Функция, определенная внутри другой функции, имеет доступ только к переменным, которые находятся в родительской функции, а также к тем, что для нее доступны.
Посмотрим на примере:
Вложенные функции и замыкания
Итак, функцию можно вложить в другую функцию! Вложенная (внутренняя) функция является «собственностью» внешней функции. Она также образует замыкание. Замыкание — это выражение (обычно функция), которое может содержать свободные переменные в окружении, связывающем эти переменные («закрывает» выражение).
Так как вложенная функция образует замыкание, можно вызвать внешнюю функцию и задать аргументы как для внешней, так и для внутренней функции.
Замыкания
Как нам уже известно, мы можем «вкладывать» функции, и JavaScript даст вложенной функции полный доступ ко всем переменным и функциям, определенным внутри внешней функции (а также к переменным и функциям, которые для нее доступны).
Однако внешняя функция не имеет доступа к переменным и функциям, определенным внутри вложенной функции! Замыкание создается, когда внутренняя функция каким-то образом становится доступной для области видимости внешней функции.
Посмотрим на примере:
Объект arguments
Аргументы любой функции содержатся в объекте, похожем на массив. Внутри функции вы можете обратиться к передаваемым аргументам следующим образом:
Например, рассмотрим функцию, которая соединяет несколько строк. Единственный формальный аргумент для функции — это строка, которая определяет, какими знаками разделять элементы. Функция будет выглядеть следующим образом:
Вы можете передать любое число аргументов в данную функцию, и она соединит каждую строку в новую строку ‘list’:
Обратите внимание: переменная arguments только похожа на массив, но это не так. У нее есть пронумерованный индекс и длина. Однако у нее нет всех методов, присущих массиву.
Параметры функции
Существует два вида параметров функции: параметры, используемые по умолчанию и оставшиеся параметры. Давайте остановимся на них подробнее.
Параметры по умолчанию
Это очень просто воплотить:
Вы можете установить 1 как значение по умолчанию для переменной b в начале функции.
Оставшиеся параметры
Синтаксис оставшихся параметров позволяет передавать неопределенное количество параметров в функцию.
В данном примере мы используем оставшиеся параметры, чтобы собрать аргументы, начиная со второго и до конца. Затем мы перемножаем их на первый. Пример использует стрелочную функцию, которую мы разберем дальше:
Стрелочные функции
Синтаксис стрелочной функции гораздо короче, по сравнению с обычным выражением функции. Например, обычная функция выглядит так:
А вот та же функция, но записанная как стрелочная:
Та функция, но записанная всего в одну строчку! Очень компактно!
Если у нас нет параметров, стрелочная функция записывается следующим образом:
Если же у нас всего один параметр, скобки не обязательны:
И наконец, если вы возвращаете выражение, скобки можно убрать:
Предопределенные функции
Стоит отметить, что в JavaScript есть множество встроенных функций! И вероятнее всего, они сэкономят вам много времени, особенно для решения простых задач.
Заключение
На сегодня все! Мы узнали об определении функций, функциональных выражениях, вызове функций, области видимости, вложенности, замыканиях, объекте arguments, параметрах функции и стрелочных функциях.