Что такое result в javascript
Функции
Функции в JavaScript
Это определяет высокую выразительную мощность JavaScript и позволяет относить его к числу языков, реализующих функциональную парадигму программирования (что само по себе есть очень круто по многим соображениям).
Функция в JavaScript специальный тип объектов, позволяющий формализовать средствами языка определённую логику поведения и обработки данных.
Для понимания работы функций необходимо (и достаточно?) иметь представление о следующих моментах:
Объявление функций
Функции вида «function declaration statement»
Объявление функции (function definition, или function declaration, или function statement) состоит из ключевого слова function и следующих частей:
Например, следующий код объявляет простую функцию с именем square:
Функция square принимает один параметр, названный number. Состоит из одной инструкции, которая означает вернуть параметр этой функции (это number ) умноженный на самого себя. Инструкция return указывает на значение, которые будет возвращено функцией.
Примитивные параметры (например, число) передаются функции значением; значение передаётся в функцию, но если функция меняет значение параметра, это изменение не отразится глобально или после вызова функции.
Если вы передадите объект как параметр (не примитив, например, массив или определяемые пользователем объекты), и функция изменит свойство переданного в неё объекта, это изменение будет видно и вне функции, как показано в следующим примере:
Функции вида «function definition expression»
Функция вида «function declaration statement» по синтаксису является инструкцией (statement), ещё функция может быть вида «function definition expression». Такая функция может быть анонимной (она не имеет имени). Например, функция square может быть вызвана так:
Однако, имя может быть и присвоено для вызова самой себя внутри самой функции и для отладчика (debugger) для идентифицированные функции в стек-треках (stack traces; «trace» — «след» / «отпечаток»).
В следующим коде наша функция принимает функцию, которая является function definition expression, и выполняет его для каждого элемента принятого массива вторым аргументом.
Функция возвращает: [0, 1, 8, 125, 1000].
В JavaScript функция может быть объявлена с условием. Например, следующая функция будет присвоена переменной myFunc только, если num равно 0:
Метод — это функция, которая является свойством объекта. Узнать больше про объекты и методы можно по ссылке: Работа с объектами.
Вызовы функций
Объявление функции не выполняет её. Объявление функции просто называет функцию и указывает, что делать при вызове функции.
Эта инструкция вызывает функцию с аргументом 5. Функция вызывает свои инструкции и возвращает значение 25.
Функции могут быть в области видимости, когда они уже определены, но функции вида «function declaration statment» могут быть подняты (поднятие — hoisting), также как в этом примере:
Область видимости функции — функция, в котором она определена, или целая программа, если она объявлена по уровню выше.
Примечание: Это работает только тогда, когда объявлении функции использует вышеупомянутый синтаксис (т.е. function funcName()<> ). Код ниже не будет работать. Имеется в виду то, что поднятие функции работает только с function declaration и не работает с function expression.
Аргументы функции не ограничиваются строками и числами. Вы можете передавать целые объекты в функцию. Функция show_props() (объявленная в Работа с объектами) является примером функции, принимающей объекты аргументом.
Функция может вызвать саму себя. Например, вот функция рекурсивного вычисления факториала:
Затем вы можете вычислить факториалы от одного до пяти следующим образом:
Область видимости функций
Переменные объявленные в функции не могут быть доступными где-нибудь вне этой функции, поэтому переменные (которые нужны именно для функции) объявляют только в scope функции. При этом функция имеет доступ ко всем переменным и функциям, объявленным внутри её scope. Другими словами функция объявленная в глобальном scope имеет доступ ко всем переменным в глобальном scope. Функция объявленная внутри другой функции ещё имеет доступ и ко всем переменным её родительской функции и другим переменным, к которым эта родительская функция имеет доступ.
Scope и стек функции
Рекурсия
Функция может вызывать саму себя. Три способа такого вызова:
Для примера рассмотрим следующие функцию:
Внутри функции (function body) все следующие вызовы эквивалентны:
Функция, которая вызывает саму себя, называется рекурсивной функцией (recursive function). Получается, что рекурсия аналогична циклу (loop). Оба вызывают некоторый код несколько раз, и оба требуют условия (чтобы избежать бесконечного цикла, вернее бесконечной рекурсии). Например, следующий цикл:
можно было изменить на рекурсивную функцию и вызовом этой функции:
Однако некоторые алгоритмы не могут быть простыми повторяющимися циклами. Например, получение всех элементов структуры дерева (например, DOM) проще всего реализуется использованием рекурсии:
Также возможно превращение некоторых рекурсивных алгоритмов в нерекурсивные, но часто их логика очень сложна, и для этого потребуется использование стека (stack). По факту рекурсия использует stack: function stack.
Поведение стека можно увидеть в следующем примере:
Вложенные функции (nested functions) и замыкания (closures)
Вы можете вложить одну функцию в другую. Вложенная функция (nested function; inner) приватная (private) и она помещена в другую функцию (outer). Так образуется замыкание (closure). Closure — это выражение (обычно функция), которое может иметь свободные переменные вместе со средой, которая связывает эти переменные (что «закрывает» («close») выражение).
Поскольку вложенная функция это closure, это означает, что вложенная функция может «унаследовать» (inherit) аргументы и переменные функции, в которую та вложена. Другими словами, вложенная функция содержит scope внешней («outer») функции.
Следующий пример показывает вложенную функцию:
Поскольку вложенная функция формирует closure, вы можете вызвать внешнюю функцию и указать аргументы для обоих функций (для outer и innner).
Сохранение переменных
Это не отличается от хранения ссылок в других объектах, но часто менее очевидно, потому что не устанавливаются ссылки напрямую и нельзя посмотреть там.
Несколько уровней вложенности функций (Multiply-nested functions)
Функции можно вкладывать несколько раз, т.е. функция (A) хранит в себе функцию (B), которая хранит в себе функцию (C). Обе функции B и C формируют closures, так B имеет доступ к переменным и аргументам A, и C имеет такой же доступ к B. В добавок, поскольку C имеет такой доступ к B, который имеет такой же доступ к A, C ещё имеет такой же доступ к A. Таким образом closures может хранить в себе несколько scope; они рекурсивно хранят scope функций, содержащих его. Это называется chaining (chain — цепь; Почему названо «chaining» будет объяснено позже)
Рассмотрим следующий пример:
Конфликты имён (Name conflicts)
Когда два аргумента или переменных в scope у closure имеют одинаковые имена, происходит конфликт имени (name conflict). Более вложенный (more inner) scope имеет приоритет, так самый вложенный scope имеет наивысший приоритет, и наоборот. Это цепочка областей видимости (scope chain). Самым первым звеном является самый глубокий scope, и наоборот. Рассмотрим следующие:
Замыкания
Closures это один из главных особенностей JavaScript. JavaScript разрешает вложенность функций и предоставляет вложенной функции полный доступ ко всем переменным и функциям, объявленным внутри внешней функции (и другим переменным и функции, к которым имеет доступ эта внешняя функция).
Однако, внешняя функция не имеет доступа к переменным и функциям, объявленным во внутренней функции. Это обеспечивает своего рода инкапсуляцию для переменных внутри вложенной функции.
Также, поскольку вложенная функция имеет доступ к scope внешней функции, переменные и функции, объявленные во внешней функции, будет продолжать существовать и после её выполнения для вложенной функции, если на них и на неё сохранился доступ (имеется ввиду, что переменные, объявленные во внешней функции, сохраняются, только если внутренняя функция обращается к ним).
Closure создаётся, когда вложенная функция как-то стала доступной в неком scope вне внешней функции.
Более сложный пример представлен ниже. Объект с методами для манипуляции вложенной функции внешней функцией можно вернуть (return).
В коде выше переменная name внешней функции доступна для вложенной функции, и нет другого способа доступа к вложенным переменным кроме как через вложенную функцию. Вложенные переменные вложенной функции являются безопасными хранилищами для внешних аргументов и переменных. Они содержат «постоянные» и «инкапсулированные» данные для работы с ними вложенными функциями. Функции даже не должны присваиваться переменной или иметь имя.
Однако есть ряд подводных камней, которые следует учитывать при использовании замыканий. Если закрытая функция определяет переменную с тем же именем, что и имя переменной во внешней области, нет способа снова ссылаться на переменную во внешней области.
Использование объекта arguments
Объект arguments функции является псевдо-массивом. Внутри функции вы можете ссылаться к аргументам следующим образом:
Для примера рассмотрим функцию, которая конкатенирует несколько строк. Единственным формальным аргументом для функции будет строка, которая указывает символы, которые разделяют элементы для конкатенации. Функция определяется следующим образом:
Вы можете передавать любое количество аргументов в эту функцию, и он конкатенирует каждый аргумент в одну строку.
Рассмотрите объект Function в JavaScript-справочнике для большей информации.
Параметры функции
Начиная с ECMAScript 2015 появились два новых вида параметров: параметры по умолчанию (default parameters) и остаточные параметры (rest parameters).
Параметры по умолчанию (Default parameters)
С параметрами по умолчанию проверка наличия значения параметра в теле функции не нужна. Теперь вы можете просто указать значение по умолчанию для параметра b в объявлении функции:
Для более детального рассмотрения ознакомьтесь с параметрами по умолчанию.
Остаточные параметры (Rest parameters)
Остаточные параметры предоставляют нам массив неопределённых аргументов. В примере мы используем остаточные параметры, чтобы собрать аргументы с индексами со 2-го до последнего. Затем мы умножим каждый из них на значение первого аргумента. В этом примере используется стрелочная функция (Arrow functions), о которой будет рассказано в следующей секции.
Стрелочные функции
Более короткие функции
В некоторых функциональных паттернах приветствуется использование более коротких функций. Сравните:
Лексика this
До стрелочных функций каждая новая функция определяла своё значение this (новый объект в случае конструктора, undefined в strict mode, контекстный объект, если функция вызвана как метод объекта, и т.д.). Это оказалось раздражающим с точки зрения объектно-ориентированного стиля программирования.
В ECMAScript 3/5 эта проблема была исправлена путём присвоения значения this переменной, которую можно было бы замкнуть.
В arrow function значением this является окружающий его контекст, так следующий код работает ожидаемо:
Далее
Подробное техническое описание функций в статье справочника Функции
Смотрите также Function в Справочнике JavaScript для получения дополнительной информации по функции как объекту.
Функции
Курс: Основы HTML и CSS
Курс: Разработка на C#
Курс: Python-разработчик с нуля
Осваивайте профессию, начните зарабатывать, а платите через год!
Курсы Python Акция! Бесплатно!
Станьте хакером на Python за 3 дня
Веб-вёрстка. CSS, HTML и JavaScript
Станьте веб-разработчиком с нуля
Функции помогают снизить повторяемость кода за счет превращения часто встречающихся участков кода в независимые блоки, которые определяются один раз и могут вызываться многократно. В этой главе описаны основы их применения и соответствующие механизмы.
JavaScript Функции
Функция (function) – это самостоятельный фрагмент кода, решающий определенную задачу. Каждой функции присваивается уникальное имя, по которому ее можно идентифицировать и «вызвать» в нужный момент.
Функции в языке JavaScript являются объектами, и следовательно ими можно манипулировать как объектами. Например, функции могут присваиваться переменным, элементам массива, свойствам объектов, передавать в качестве аргумента функциям и возвращать в качестве значения из функций.
Объявление и вызов функции
Функция (как и всякий объект) должна быть объявлена (определена) перед её использованием.
Синтаксис функции JavaScript:
Программный код, расположенный в теле функции, выполняется не в момент объявления функции, а в момент её вызова. Будучи один раз определенной, функция может сколько угодно раз вызываться с помощью оператора () (вызов функции):
Этот код выведет нам приветствие в диалоговом окне alert() два раза. Применение функции позволило нам избавиться от дублирования кода.
Обратившись к переменной с именем созданной функции можно увидеть, что в качестве значения там находится функция (а точнее ссылка на неё):
Ссылку на функцию вы можете сохранить в любой переменной, например:
«Классическое» объявление функции function имя(параметры) <код>называется в спецификации языка «Function Declaration».
Существует альтернативный синтаксис для объявления функции «Function Expression» (функциональное выражение) – это объявление функции, которое является частью какого-либо выражения (например присваивания):
Если у функции нет имени, как в предыдущем примере, она называется «анонимной».
Разница между представленными объявлениями заключается в том, что функции, объявленные как «Function Declaration», создаются интерпретатором до начала выполнения кода (на этапе анализа), поэтому их можно вызвать до объявления:
Параметры и аргументы
Параметр функции – это переменная в функции, которая будет содержать передаваемое снаружи входное значение. Параметры функции перечислены внутри круглых скобок () в определении функции.
Для определения параметров функции используется следующий синтаксис:
Параметры следует рассматривать как объявления локальных переменных в теле функции, каждая из которых инициализируются в момент вызова функции соответствующим значением из списка аргументов (или значением по умолчанию).
Аргументы функции — это значения, которые вы предоставляете функции в момент её вызова.
Для вызова функции с передачей ей аргументов используется следующий синтаксис:
Например, при вызове функции sum ей передаются два аргумента:
Аргументы, передаваемые функции при её вызове, присваиваются параметрам функции в том порядке, в каком они указаны: первый аргумент присваивается первому параметру, второй аргумент – второму параметру и т. д.
Типы аргументов, передаваемых функции при её вызове, могут быть как примитивами (строки, числа, логические величины (boolean)), так и объектами (в т.ч. массивы и функции).
При передаче в качестве аргумента объекта все происходит не так, как было с примитивными значениями. В таком случае копия объекта не создается – объекты передаются в функцию по ссылке. Переприсваивание самой ссылки также не будет иметь внешнего эффекта, но если в теле функции изменяются свойства объекта, то эти изменения будут видимы вне функции (побочный эффект). Поэтому, всегда следует помнить, что в функции содержится оригинальный объект.
Возвращаемые значения
Функции могут не только принимать входящие данные из внешней программы, но и способны передавать обратно значения по завершении своих инструкций. Для возврата значения используется инструкция return.
Инструкция return имеет следующий синтаксис:
В программу, вызвавшую функцию, возвращается не само выражение, а результат его вычисления. Например, функция sum возвращает сумму двух чисел:
Функции
Зачастую нам надо повторять одно и то же действие во многих частях программы.
Например, необходимо красиво вывести сообщение при приветствии посетителя, при выходе посетителя с сайта, ещё где-нибудь.
Чтобы не повторять один и тот же код во многих местах, придуманы функции. Функции являются основными «строительными блоками» программы.
Объявление функции
Для создания функций мы можем использовать объявление функции.
Пример объявления функции:
Вызов showMessage() выполняет код функции. Здесь мы увидим сообщение дважды.
Этот пример явно демонстрирует одно из главных предназначений функций: избавление от дублирования кода.
Если понадобится поменять сообщение или способ его вывода – достаточно изменить его в одном месте: в функции, которая его выводит.
Локальные переменные
Переменные, объявленные внутри функции, видны только внутри этой функции.
Внешние переменные
У функции есть доступ к внешним переменным, например:
Функция обладает полным доступом к внешним переменным и может изменять их значение.
Внешняя переменная используется, только если внутри функции нет такой локальной.
Переменные, объявленные снаружи всех функций, такие как внешняя переменная userName в вышеприведённом коде – называются глобальными.
Глобальные переменные видимы для любой функции (если только их не перекрывают одноимённые локальные переменные).
Желательно сводить использование глобальных переменных к минимуму. В современном коде обычно мало или совсем нет глобальных переменных. Хотя они иногда полезны для хранения важнейших «общепроектовых» данных.
Параметры
Мы можем передать внутрь функции любую информацию, используя параметры (также называемые аргументами функции).
Параметры по умолчанию
Например, вышеупомянутая функция showMessage(from, text) может быть вызвана с одним аргументом:
Если мы хотим задать параметру text значение по умолчанию, мы должны указать его после = :
Теперь, если параметр text не указан, его значением будет «текст не добавлен»
В данном случае «текст не добавлен» это строка, но на её месте могло бы быть и более сложное выражение, которое бы вычислялось и присваивалось при отсутствии параметра. Например:
В JavaScript параметры по умолчанию вычисляются каждый раз, когда функция вызывается без соответствующего параметра.
Ранние версии JavaScript не поддерживали параметры по умолчанию. Поэтому существуют альтернативные способы, которые могут встречаться в старых скриптах.
Например, явная проверка на undefined :
…Или с помощью оператора || :
Возврат значения
Функция может вернуть результат, который будет передан в вызвавший её код.
Простейшим примером может служить функция сложения двух чисел:
Директива return может находиться в любом месте тела функции. Как только выполнение доходит до этого места, функция останавливается, и значение возвращается в вызвавший её код (присваивается переменной result выше).
Вызовов return может быть несколько, например:
Возможно использовать return и без значения. Это приведёт к немедленному выходу из функции.
Если функция не возвращает значения, это всё равно, как если бы она возвращала undefined :
Пустой return аналогичен return undefined :
Для длинного выражения в return может быть заманчиво разместить его на нескольких отдельных строках, например так:
И тогда всё сработает, как задумано.
Выбор имени функции
Функция – это действие. Поэтому имя функции обычно является глаголом. Оно должно быть простым, точным и описывать действие функции, чтобы программист, который будет читать код, получил верное представление о том, что делает функция.
Как правило, используются глагольные префиксы, обозначающие общий характер действия, после которых следует уточнение. Обычно в командах разработчиков действуют соглашения, касающиеся значений этих префиксов.
Например, функции, начинающиеся с «show» обычно что-то показывают.
Функции, начинающиеся с…
Примеры таких имён:
Благодаря префиксам, при первом взгляде на имя функции становится понятным что делает её код, и какое значение она может возвращать.
Функция должна делать только то, что явно подразумевается её названием. И это должно быть одним действием.
Два независимых действия обычно подразумевают две функции, даже если предполагается, что они будут вызываться вместе (в этом случае мы можем создать третью функцию, которая будет их вызывать).
Несколько примеров, которые нарушают это правило:
В этих примерах использовались общепринятые смыслы префиксов. Конечно, вы в команде можете договориться о других значениях, но обычно они мало отличаются от общепринятых. В любом случае вы и ваша команда должны точно понимать, что значит префикс, что функция с ним может делать, а чего не может.
Имена функций, которые используются очень часто, иногда делают сверхкороткими.
Это исключения. В основном имена функций должны быть в меру краткими и описательными.
Функции == Комментарии
Функции должны быть короткими и делать только что-то одно. Если это что-то большое, имеет смысл разбить функцию на несколько меньших. Иногда следовать этому правилу непросто, но это определённо хорошее правило.
Небольшие функции не только облегчают тестирование и отладку – само существование таких функций выполняет роль хороших комментариев!
Первый вариант использует метку nextPrime :
Второй вариант использует дополнительную функцию isPrime(n) для проверки на простое:
Второй вариант легче для понимания, не правда ли? Вместо куска кода мы видим название действия ( isPrime ). Иногда разработчики называют такой код самодокументируемым.
Таким образом, допустимо создавать функции, даже если мы не планируем повторно использовать их. Такие функции структурируют код и делают его более понятным.
Итого
Объявление функции имеет вид:
Для того, чтобы сделать код более чистым и понятным, рекомендуется использовать локальные переменные и параметры функций, не пользоваться внешними переменными.
Функция, которая получает параметры, работает с ними и затем возвращает результат, гораздо понятнее функции, вызываемой без параметров, но изменяющей внешние переменные, что чревато побочными эффектами.
Функции являются основными строительными блоками скриптов. Мы рассмотрели лишь основы функций в JavaScript, но уже сейчас можем создавать и использовать их. Это только начало пути. Мы будем неоднократно возвращаться к функциям и изучать их всё более и более глубоко.
Задачи
Обязателен ли «else»?
В ином случае она запрашивает подтверждение через confirm и возвращает его результат:
Есть ли хоть одно отличие в поведении этого варианта?
Оба варианта функций работают одинаково, отличий нет.
Перепишите функцию, используя оператор ‘?’ или ‘||’
В ином случае она задаёт вопрос confirm и возвращает его результат.
Сделайте два варианта функции checkAge :