- функции
- Объявление функций
- Функции вида «function declaration statement»
- Функции вида «function definition expression»
- Вызовы функций
- Область видимости функций
- Scope и стек функции
- Рекурсия
- Вложенные функции (nested functions) и замыкания (closures)
- Сохранение переменных
- Несколько уровней вложенности функций (Multiply-nested functions)
- Конфликты имён (Name conflicts)
- Замыкания
- Использование объекта arguments
- Параметры функции
- Параметры по умолчанию (Default parameters)
- Остаточные параметры (Rest parameters)
- Стрелочные функции
- Более короткие функции
- Лексика
- Далее
- Тестирование по охране труда в ЕИСОТ. Порядок прохождения и примеры реальных вопросов
- Кто должен проходить тестирование
- Что проверяют?
- Как получить доступ к тестированию ЕИСОТ
- Прохождение тестирования
- Примеры вопросов по всем разделам теста ЕИСОТ
- Программа А
- Программа Б
- Программа В
- Использование СИЗ
- Первая помощь
- Объявление функции
- Локальные переменные
- Внешние переменные
- Параметры
- Значения по умолчанию
- Альтернативные параметры по умолчанию
- Возврат значения
- Выбор имени функции
- Функции == Комментарии
- Итого
функции
Функции — ключевая концепция в JavaScript. Важнейшей особенностью языка является поддержка
функции первого класса
передавать как аргумент и возвращать в качестве результата при вызове других функций функций высшего порядка;
создавать анонимно и присваивать в качестве значений переменных или свойств объектов.
Это определяет высокую выразительную мощность JavaScript и позволяет относить его к числу языков, реализующих
функциональную парадигму программирования
.
Функция в JavaScript
специальный тип объектов, позволяющий формализовать средствами языка определённую логику поведения и обработки данных.
Для понимания работы функций необходимо (и достаточно?) иметь представление о следующих моментах:
- способы объявления
- способы вызова
- параметры и аргументы вызова (
arguments) - область данных (
Scope) и замыкания (Closures) - объект привязки (
this) - возвращаемое значение (
return) - исключения (
throw) - использование в качестве конструктора объектов
- сборщик мусора (
garbage collector)
Объявление функций
Функции вида «function declaration statement»
Объявление функции (
function definition
, или
function declaration
, или
function statement
) состоит из ключевого слова
- Имя функции.
- Список параметров (принимаемых функцией) заключённых в круглые скобки
()и разделённых запятыми. - Инструкции, которые будут выполнены после вызова функции, заключают в фигурные скобки
{ }.
Например, следующий код объявляет простую функцию с именем
number number
Функция
Примитивные параметры (например, число) передаются функции значением;
значение
передаётся в функцию, но если функция меняет значение параметра,
это изменение не отразится глобально или после вызова функции.
Если вы передадите объект как параметр (не примитив, например,
theObjectmake
mycar
x y
x mycarmake // x получает значение "Honda"
mycar
y mycarmake // y получает значение "Toyota"
// (свойство было изменено функцией)
Функции вида «function definition expression»
Функция вида «function declaration statement» по синтаксису является инструкцией (
number number
x // x получает значение 16
Однако, имя может быть и присвоено для вызова самой себя внутри самой функции и для отладчика (
debugger
) для идентифицированные функции в стек-треках (
stack traces
; «trace» — «след» / «отпечаток»).
n n n
console
Функции вида «function definition expression» удобны, когда функция передаётся аргументом другой функции. Следующий пример показывает функцию
result // Создаём новый массив
i
i i alength i resulti ai
result
В следующем коде наша функция принимает функцию, которая является function definition expression, и выполняет его для каждого элемента принятого массива вторым аргументом.
result // Создаём новый массив
i // Объявляем переменную
i i alength i resulti ai
result
x x x
numbers
cube f numbers
consolecube
В JavaScript функция может быть объявлена с условием. Например, следующая функция будет присвоена переменной
myFunc
num
theObjectmake
В дополнение к объявлениям функций, описанных здесь, вы также можете использовать конструктор
Function
для создания функций из строки во время выполнения (
runtime
), подобно
Вызовы функций
Объявление функции не выполняет её. Объявление функции просто называет функцию и указывает, что делать при вызове функции.
функции фактически выполняет указанные действия с указанными параметрами. Например, если вы определите функцию
Эта инструкция вызывает функцию с аргументом 5. Функция вызывает свои инструкции и возвращает значение 25.
Функции могут быть в области видимости, когда они уже определены, но функции вида «function declaration statement» могут быть подняты (
console
n n
Область видимости функции — функция, в котором она определена, или целая программа, если она объявлена по уровню выше.
consolesquare // square поднят со значением undefined.
console // TypeError: square is not a function
n n
Аргументы функции не ограничиваются строками и числами. Вы можете передавать целые объекты в функцию. Функция
Функция может вызвать саму себя. Например, вот функция рекурсивного вычисления факториала:
n n
n n
Затем вы можете вычислить факториалы от одного до пяти следующим образом:
a b c d e
a // a получает значение 1
b // b получает значение 2
c // c получает значение 6
d // d получает значение 24
e // e получает значение 120
Есть другие способы вызвать функцию. Существуют частые случаи, когда функции необходимо вызывать динамически, или поменять номера аргументов функции, или необходимо вызвать функцию с привязкой к определённому контексту. Оказывается, что функции сами по себе являются объектами, и эти объекты в свою очередь имеют методы (посмотрите объект
Область видимости функций
Переменные объявленные в функции не могут быть доступными где-нибудь вне этой функции, поэтому переменные (которые нужны именно для функции) объявляют только в scope функции. При этом функция имеет доступ ко всем переменным и функциям, объявленным внутри её scope. Другими словами функция объявленная в глобальном scope имеет доступ ко всем переменным в глобальном scope. Функция объявленная внутри другой функции ещё имеет доступ и ко всем переменным её родительской функции и другим переменным, к которым эта родительская функция имеет доступ.
// Следующие переменные объявленны в глобальном scope
num1
num2
name
// Эта функция объявленна в глобальном scope
num1 num2
// вернёт 60
// Пример вложенной функции
num1
num2
name " scored " num1 num2
// вернёт "Chamahk scored 5"
Scope и стек функции
Рекурсия
Функция может вызывать саму себя. Три способа такого вызова:
по имени функции
по переменной, которая ссылается на функцию
Для примера рассмотрим следующие функцию:
// здесь будут выражения
Внутри функции (
function body
) все следующие вызовы эквивалентны:
bar()arguments.callee()foo()
Функция, которая вызывает саму себя, называется
рекурсивной функцией
(
recursive function
). Получается, что рекурсия аналогична циклу (
loop
). Оба вызывают некоторый код несколько раз, и оба требуют условия (чтобы избежать бесконечного цикла, вернее бесконечной рекурсии). Например, следующий цикл:
x
x
// "x < 10" — это условие для цикла
// что-то делаем
x
можно было изменить на рекурсивную функцию и вызовом этой функции:
x
// "x >= 10" — это условие для конца выполнения (тоже самое, что "!(x < 10)")
// делать что-то
x // рекурсионный вызов
Однако некоторые алгоритмы не могут быть простыми повторяющимися циклами. Например, получение всех элементов структуры дерева (например,
DOM
) проще всего реализуется использованием рекурсии:
node
// что-то делаем с элементами
i i nodechildNodeslength i
nodechildNodesi
В сравнении с функцией
Также возможно превращение некоторых рекурсивных алгоритмов в нерекурсивные, но часто их логика очень сложна, и для этого потребуется использование стека (
stack
). По факту рекурсия использует stack: function stack.
Поведение стека можно увидеть в следующем примере:
i
console i
i
console i
// begin: 3
// begin: 2
// begin: 1
// begin: 0
// end: 0
// end: 1
// end: 2
// end: 3
Вложенные функции (nested functions) и замыкания (closures)
Вы можете вложить одну функцию в другую. Вложенная функция (
nested function
;
inner
) приватная (
private
) и она помещена в другую функцию (
outer
). Так образуется
замыкание
(
closure
). Closure — это выражение (обычно функция), которое может иметь свободные переменные вместе со средой, которая связывает эти переменные (что «закрывает» (
«close»
) выражение).
Поскольку вложенная функция это closure, это означает, что вложенная функция может «унаследовать» (
inherit
) аргументы и переменные функции, в которую та вложена. Другими словами, вложенная функция содержит scope внешней (
«outer»
) функции.
- Вложенная функция имеет доступ ко всем инструкциям внешней функции.
- Вложенная функция формирует closure: она может использовать аргументы и переменные внешней функции, в то время как внешняя функция не может использовать аргументы и переменные вложенной функции.
Следующий пример показывает вложенную функцию:
x x
a b
a // возвращает 13
b // возвращает 25
c // возвращает 41
Поскольку вложенная функция формирует closure, вы можете вызвать внешнюю функцию и указать аргументы для обоих функций (для outer и innner).
x y
inside
fn_inside // Думайте об этом как: дайте мне функцию,
// которая добавляет 3 к любому введенному значению
result // возвращает 8
result1 // возвращает 8
Сохранение переменных
Обратите внимание, значение
Это не отличается от хранения ссылок в других объектах, но часто менее очевидно, потому что не устанавливаются ссылки напрямую и нельзя посмотреть там.
Несколько уровней вложенности функций (Multiply-nested functions)
Функции можно вкладывать несколько раз, т.е. функция (A) хранит в себе функцию (B), которая хранит в себе функцию (C). Обе функции B и C формируют closures, так B имеет доступ к переменным и аргументам A, и C имеет такой же доступ к B. В добавок, поскольку C имеет такой доступ к B, который имеет такой же доступ к A, C ещё имеет такой же доступ к A. Таким образом closures может хранить в себе несколько scope; они рекурсивно хранят scope функций, содержащих его. Это называется
chaining
(
chain — цепь
; Почему названо «chaining» будет объяснено позже)
Рассмотрим следующий пример:
consolex y z
// в консоле выводится 6 (1 + 2 + 3)
В этом примере C имеет доступ к
- Функция
Bформирует closure, включающееA, т.е.Bимеет доступ к аргументам и переменным функцииA. - Функция
Cформирует closure, включающееB. - Раз closure функции
BвключаетA, то closureСтоже включает A,Cимеет доступ к аргументам и переменным обоих функцийBиA. Другими словами,Ссвязывает цепью (chain) scopes функцийBиAв таком порядке.
В обратном порядке, однако, это не верно.
Конфликты имён (Name conflicts)
Когда два аргумента или переменных в scope у closure имеют одинаковые имена, происходит
конфликт имени
(
name conflict
). Более вложенный (
more inner
) scope имеет приоритет, так самый вложенный scope имеет наивысший приоритет, и наоборот. Это цепочка областей видимости (
scope chain
). Самым первым звеном является самый глубокий scope, и наоборот. Рассмотрим следующие:
x
x
inside
// возвращает 20 вместо 10
Замыкания
Closures это один из главных особенностей JavaScript. JavaScript разрешает вложенность функций и предоставляет вложенной функции полный доступ ко всем переменным и функциям, объявленным внутри внешней функции (и другим переменным и функции, к которым имеет доступ эта внешняя функция).
Однако, внешняя функция не имеет доступа к переменным и функциям, объявленным во внутренней функции. Это обеспечивает своего рода инкапсуляцию для переменных внутри вложенной функции.
Также, поскольку вложенная функция имеет доступ к scope внешней функции, переменные и функции, объявленные во внешней функции, будет продолжать существовать и после её выполнения для вложенной функции, если на них и на неё сохранился доступ (имеется ввиду, что переменные, объявленные во внешней функции, сохраняются, только если внутренняя функция обращается к ним).
Closure создаётся, когда вложенная функция как-то стала доступной в неком scope вне внешней функции.
// Внешняя функция объявила переменную "name"
name // Вложенная функция имеет доступ к "name" внешней функции
getName // Возвращаем вложенную функцию, тем самым сохраняя доступ
// к ней для другого scope
myPet
// Возвращается "Vivie",
// т.к. даже после выполнения внешней функции
// name сохранился для вложенной функции
Более сложный пример представлен ниже. Объект с методами для манипуляции вложенной функции внешней функцией можно вернуть (
return
).
sex
name newName
name
sex
newSex
newSex newSex
sex newSex
pet
pet
pet
pet
pet
pet
В коде выше переменная
getCode
apiCode
apiCode
// Возвращает apiCode
Однако есть ряд подводных камней, которые следует учитывать при использовании замыканий. Если закрытая функция определяет переменную с тем же именем, что и имя переменной во внешней области, нет способа снова ссылаться на переменную во внешней области.
// Внешняя функция определяет переменную с именем "name".
// Внутренняя функция также определяет переменную с именем "name".
name name // Как мы можем получить доступ к "name", определённой во внешней функции?
Использование объекта arguments
Объект arguments функции является псевдо-массивом. Внутри функции вы можете ссылаться к аргументам следующим образом:
С помощью объекта
Для примера рассмотрим функцию, которая конкатенирует несколько строк. Единственным формальным аргументом для функции будет строка, которая указывает символы, которые разделяют элементы для конкатенации. Функция определяется следующим образом:
result
i
// iterate through arguments
i i argumentslength i
result argumentsi separator
result
Вы можете передавать любое количество аргументов в эту функцию, и он конкатенирует каждый аргумент в одну строку.
// возвращает "red, orange, blue, "
// возвращает "elephant; giraffe; lion; cheetah; "
// возвращает "sage. basil. oregano. pepper. parsley. "
является псевдо-массивом, но не массивом. Это псевдо-массив, в котором есть пронумерованные индексы и свойство
Рассмотрите объект
Параметры функции
Начиная с ECMAScript 2015 появились два новых вида параметров: параметры по умолчанию (
default parameters
) и остаточные параметры (
rest parameters
).
Параметры по умолчанию (Default parameters)
В JavaScript параметры функции по умолчанию имеют значение
В прошлом для этого было необходимо в теле функции проверять значения параметров на
b b b
a b
С параметрами по умолчанию проверка наличия значения параметра в теле функции не нужна. Теперь вы можете просто указать значение по умолчанию для параметра
a b
a b
Для более детального рассмотрения ознакомьтесь с
параметрами по умолчанию
.
Остаточные параметры (Rest parameters)
Остаточные параметры
предоставляют нам массив неопределённых аргументов. В примере мы используем остаточные параметры, чтобы собрать аргументы с индексами со 2-го до последнего. Затем мы умножим каждый из них на значение первого аргумента. В этом примере используется стрелочная функция (
theArgs multiplier x
arr
consolearr
Стрелочные функции
На введение стрелочных функций повлияли два фактора: более короткие функции и лексика
Более короткие функции
В некоторых функциональных паттернах приветствуется использование более коротких функций. Сравните:
a
a2 a
slength
consolea2
a3 a slength
consolea3
Лексика
До стрелочных функций каждая новая функция определяла своё значение
// Конструктор Person() определяет `this` как самого себя.
age
// Без strict mode функция growUp() определяет `this`
// как global object, который отличается от `this`
// определённого конструктором Person().
age
p
В ECMAScript 3/5 эта проблема была исправлена путём присвоения значения
self // Некоторые выбирают `that` вместо `self`.
// Выберите что-то одно и будьте последовательны.
selfage
// Колбэк ссылается на переменную `self`,
// значением которой является ожидаемый объект.
selfage
Альтернативой может быть
В arrow function значением
age
age
p
Далее
Подробное техническое описание функций в статье справочника
Тестирование по охране труда в ЕИСОТ. Порядок прохождения и примеры реальных вопросов
Тестирование по охране труда в ЕИСОТ. Порядок прохождения и примеры реальных вопросов
С 1 марта 2023 года все специалисты по охране труда, руководители подразделений и члены внутренней комиссии по обучению охране труда должны пройти обязательное тестирование в единой общероссийской справочно-информационной системе по охране труда. В статье разбираем, из чего состоит тестирование, как получить к нему доступ, сколько попыток дается на сдачу и приводим примеры реальных вопросов теста с правильными ответами по каждой программе.

Руководитель направления охраны труда учебного центра EcoStandard group
Обзоры, интервью, свежие новости и изменения в законодательстве — оперативно в нашем . О самых важных событиях — в нашей группе .
Кто должен проходить тестирование
С 1 марта 2023 года согласно п. 78
постановления
Правительства РФ № 2464 «О порядке обучения по охране труда и проверки знания требований охраны труда» (далее — Постановление),
руководители и специалисты подразделений охраны труда
должны обязательно пройти проверку знания в виде тестирования в Единой общероссийской справочно-информационной системе по охране труда (ЕИСОТ). По разъяснению Игоря Цирина, советника генерального директора ФГБУ «ВНИИ труда» Минтруда России, помимо руководителей и специалистов подразделений охраны труда тестирование должны пройти
члены комиссий по внутреннему обучению ОТ
.
Нужно ли проходить тестирование в ЕИСОТ членам комиссии по внутреннему обучению требованиям охраны труда? Чтобы ответить на этот вопрос, обратимся к подпункту Г пункта 96 Постановления, согласно которому работодатель, проводящий обучение работников требованиям охраны труда, обучение по оказанию первой помощи пострадавшим, обучение по использованию (применению) средств индивидуальной защиты, должен иметь комиссию по проверке знания требований охраны труда, сформированную в соответствии с положениями раздела VII настоящих Правил.
Пункт 78 Постановления, который вводит требования к прохождению тестирования, как раз находится в вышеупомянутом разделе VII. Из этого следует однозначный вывод:
члены комиссии работодателя также проходят проверку знания требований охраны труда путем тестирования с использованием ЕИСОТ
.
Cоветник генерального директора ФГБУ ВНИИ труда Минтруда России
Что проверяют?
В тестирование входит проверка знаний по результатам обучения:
по первой помощи;
по применению СИЗ;
по программе А (общие вопросы охраны труда и функционирования СУОТ);
по программе Б (безопасные методы и приемы выполнения работ при воздействии вредных факторов);
по программе В (работы повышенной опасности) в случае, если специалист/руководитель ответственен за работы повышенной опасности, сам их выполняет или входит в соответствующую комиссию по проверке знаний. Причем если работник выполняет несколько видов работ, специалист/руководитель должен пройти тестирование по каждой из них.
Как получить доступ к тестированию ЕИСОТ
Назначить обучение на портале можно только в организации или у индивидуального предпринимателя, оказывающих услуги по обучению работодателей и работников вопросам охраны труда (далее — учебный центр) и имеющих аккредитацию на данный вид деятельности. Рассмотрим процесс получения доступа для прохождения тестирования.
Для предоставления доступа к тестированию учебный центр запрашивает у вас следующие данные: ФИО, номер СНИЛС, электронную почту, номер телефона и компанию, в которой вы работаете. После получения данных определяется контингент, к которому вы относитесь:
КТ1 Заместитель руководителя, в ведении которого находятся вопросы охраны труда, руководители структурных подразделений органов исполнительной власти субъектов Российской Федерации (п. 52 Постановления).
КТ2 Специалисты, осуществляющие функции специалиста по охране труда органов исполнительной власти субъектов Российской Федерации (п. 52 Постановления).
КТ3 Руководители подразделений по охране труда и специалисты в области охраны труда организаций (п. 78 Постановления).
КТ4 Руководители и преподаватели организации или ИП, оказывающих услуги по обучению работодателей и работников вопросам охраны труда, которые принимают участие в работе комиссий по проверке знания требований охраны труда работников (п.78 Постановления).
КТ5 Специалисты организации и ИП, предполагающие оказывать услуги по осуществлению функции службы охраны труда или специалиста по охране труда работодателя (п.6 Постановления).
КТ6 Специалисты организации и ИП, предполагающие оказывать услуги по обучению по общим вопросам охраны труда и функционирования охраной труда (пп. А п. 7 Постановления).
КТ7 Специалисты, проводящие обучение безопасным методам и приемам выполнения работ при воздействии вредных и (или) опасных производственных факторов, опасностей, идентифицированных в рамках специальной оценки условий труда, и оценки профессиональных рисков.
КТ8 Специалисты, проводящие обучение работодателей и работников безопасным методам и приемам выполнения работ повышенной опасности в соответствии с нормативными правовыми актами (пп. В п.7 Постановления).
КТ9 Работник организации или ИП, оказывающий услуги по обучению работодателей и работников вопросам охраны труда по оказанию первой помощи пострадавшим (пп. Г п.7 Постановления).
КТ10 Члены комиссии (единой или специализированной для обучения по программе В) по проверке знания требований охраны труда, сформированной в соответствии с положениями раздела VII Постановления (пп. Г п. 96 Постановления).
Наличие пункта КТ10 еще раз подтверждает то, что тестирование сдавать необходимо не только специалистам по охране труда и их руководителям, но и всем членам внутренней комиссии по обучению и проверке знания требований ОТ.
После определения контингента учебный центр определяет, по каким программам вы будете проходить тестирование (обо всех программах мы рассказали в предыдущем разделе). В них обязательно войдут программы А, Б и обучение по первой помощи. Если ваши работники носят средства индивидуальной защиты, то обучение по применению СИЗ также будут проверять в рамках тестирования. В случае, если вы входите в комиссию по проверке знаний выполнения работ повышенной опасности, вам нужно будет пройти тестирование по программе В — для этого вы сообщаете учебному центру, какие работы повышенной опасности выполняют работники. В ЕИСОТ 24 программы по работам повышенной опасности:
На каждую из назначенных программ сдается отдельный тест. В итоговый протокол будет записано название программы, по которой пройдена проверка знаний.
Прохождение тестирования
К тестированию нужно приступать в назначенный учебным центром день — пройти до или после этого дня не получится, поэтому рекомендуем заранее согласовать день прохождения тестирования. Приступать к тестированию следует сразу после получения кода доступа, так как код периодически обновляется и может стать недействительным. Тест по каждой программе состоит из 30 вопросов, время на прохождение тестирования — 45 минут.
Если вы не сдадите тест с первого раза, у вас будет бесконечное количество попыток на пересдачу, но каждая из них предоставляется ровно через сутки после неудачного прохождения теста. Данные обо всех попытках учебный центр заносит в реестр обученных по охране труда лиц (в соответствие с пп. А п. 118 Постановления). После успешной сдачи теста учебный центр получает из реестра номер протокола обучения, а вы считаетесь обученным по охране труда в учебном центре.
В конце теста программа покажет процент верных ответов и результат проверки знаний. Тест считается сданным при 80% и более правильных ответов. Программа автоматически формирует выписку с результатами по каждому вопросу.
Пройти обучение по охране труда и другим направлениям вы можете в учебном центре EcoStandard group
Примеры вопросов по всем разделам теста ЕИСОТ
Приведем по 30 реальных вопросов тестирования с правильными ответами из каждого раздела. Мы не стали включать в нашу подборку вопросы с картинками, на которых нужно идентифицировать нарушения требований ОТ, распознать виды кровотечений и т.д., но будьте готовы к тому, что они могут быть в тестировании.
Программа А
Программа Б
Программа В
Использование СИЗ
Первая помощь
Нажав кнопку, вы даете согласие на обработку
Зачастую нам надо повторять одно и то же действие во многих частях программы.
Например, необходимо красиво вывести сообщение при приветствии посетителя, при выходе посетителя с сайта, ещё где-нибудь.
Чтобы не повторять один и тот же код во многих местах, придуманы функции. Функции являются основными «строительными блоками» программы.
Примеры встроенных функций вы уже видели – это
Объявление функции
Для создания функций мы можем использовать
объявление функции
.
Пример объявления функции:
function showMessage() {
alert( 'Всем привет!' );
}Вначале идёт ключевое слово
function имя(параметры) {
...тело...
}Наша новая функция может быть вызвана по своему имени:
function showMessage() {
alert( 'Всем привет!' );
}
showMessage();
showMessage();Вызов
Этот пример явно демонстрирует одно из главных предназначений функций: избавление от дублирования кода.
Если понадобится поменять сообщение или способ его вывода – достаточно изменить его в одном месте: в функции, которая его выводит.
Локальные переменные
Переменные, объявленные внутри функции, видны только внутри этой функции.
function showMessage() {
let message = "Привет, я JavaScript!"; // локальная переменная
alert( message );
}
showMessage(); // Привет, я JavaScript!
alert( message ); // <-- будет ошибка, т.к. переменная видна только внутри функцииВнешние переменные
У функции есть доступ к внешним переменным, например:
let userName = 'Вася';
function showMessage() {
let message = 'Привет, ' + userName;
alert(message);
}
showMessage(); // Привет, ВасяФункция обладает полным доступом к внешним переменным и может изменять их значение.
let userName = 'Вася';
function showMessage() {
userName = "Петя"; // (1) изменяем значение внешней переменной
let message = 'Привет, ' + userName;
alert(message);
}
alert( userName ); // Вася перед вызовом функции
showMessage();
alert( userName ); // Петя, значение внешней переменной было изменено функциейВнешняя переменная используется, только если внутри функции нет такой локальной.
let userName = 'Вася';
function showMessage() {
let userName = "Петя"; // объявляем локальную переменную
let message = 'Привет, ' + userName; // Петя
alert(message);
}
// функция создаст и будет использовать свою собственную локальную переменную userName
showMessage();
alert( userName ); // Вася, не изменилась, функция не трогала внешнюю переменнуюГлобальные переменные
видимы для любой функции (если только их не перекрывают одноимённые локальные переменные).
Желательно сводить использование глобальных переменных к минимуму. В современном коде обычно мало или совсем нет глобальных переменных. Хотя они иногда полезны для хранения важнейших «общепроектовых» данных.
Параметры
Мы можем передать внутрь функции любую информацию, используя параметры.
В нижеприведённом примере функции передаются два параметра:
function showMessage(from, text) { // параметры: from, text
alert(from + ': ' + text);
}
showMessage('Аня', 'Привет!'); // Аня: Привет! (*)
showMessage('Аня', "Как дела?"); // Аня: Как дела? (**)Когда функция вызывается в строках
Вот ещё один пример: у нас есть переменная
function showMessage(from, text) {
from = '*' + from + '*'; // немного украсим "from"
alert( from + ': ' + text );
}
let from = "Аня";
showMessage(from, "Привет"); // *Аня*: Привет
// значение "from" осталось прежним, функция изменила значение локальной переменной
alert( from ); // АняЗначение, передаваемое в качестве параметра функции, также называется
аргументом
.
Параметр – это переменная, указанная в круглых скобках в объявлении функции.
Аргумент – это значение, которое передаётся функции при её вызове.
Мы объявляем функции со списком параметров, затем вызываем их, передавая аргументы.
Рассматривая приведённый выше пример, мы могли бы сказать: «функция
Значения по умолчанию
Если при вызове функции аргумент не был указан, то его значением становится
Например, вышеупомянутая функция
Это не приведёт к ошибке. Такой вызов выведет
Если мы хотим задать параметру
function showMessage(from, text = "текст не добавлен") {
alert( from + ": " + text );
}
showMessage("Аня"); // Аня: текст не добавленТеперь, если параметр
В данном случае
function showMessage(from, text = anotherFunction()) {
// anotherFunction() выполнится только если не передан text
// результатом будет значение text
}Вычисление параметров по умолчанию
В JavaScript параметры по умолчанию вычисляются каждый раз, когда функция вызывается без соответствующего параметра.
В приведённом выше примере, функция
С другой стороны, функция будет независимо вызываться каждый раз, когда
Использование параметров по умолчанию в ранних версиях JavaScript
Ранние версии JavaScript не поддерживали параметры по умолчанию. Поэтому существуют альтернативные способы, которые могут встречаться в старых скриптах.
Например, явная проверка на
function showMessage(from, text) {
if (text === undefined) {
text = 'текст не добавлен';
}
alert( from + ": " + text );
}function showMessage(from, text) {
// Если значение text ложно, тогда присвоить параметру text значение по умолчанию
// заметим, что при этом пустая строка text === "" будет также считаться отсутствующим значением
text = text || 'текст не добавлен';
...
}Альтернативные параметры по умолчанию
Иногда имеет смысл присваивать значения по умолчанию для параметров не в объявлении функции, а на более позднем этапе.
Во время выполнения функции мы можем проверить, передан ли параметр, сравнив его с
function showMessage(text) {
// ...
if (text === undefined) { // если параметр отсутствует
text = 'пустое сообщение';
}
alert(text);
}
showMessage(); // пустое сообщениеfunction showMessage(text) {
// если значение text ложно или равняется undefined, тогда присвоить text значение 'пусто'
text = text || 'пусто';
...
}Современные движки JavaScript поддерживают
function showCount(count) {
// если count равен undefined или null, показать "неизвестно"
alert(count ?? "неизвестно");
}
showCount(0); // 0
showCount(null); // неизвестно
showCount(); // неизвестноВозврат значения
Функция может вернуть результат, который будет передан в вызвавший её код.
Простейшим примером может служить функция сложения двух чисел:
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
alert( result ); // 3Директива
Вызовов
function checkAge(age) {
if (age >= 18) {
return true;
} else {
return confirm('А родители разрешили?');
}
}
let age = prompt('Сколько вам лет?', 18);
if ( checkAge(age) ) {
alert( 'Доступ получен' );
} else {
alert( 'Доступ закрыт' );
}Возможно использовать
function showMovie(age) {
if ( !checkAge(age) ) {
return;
}
alert( "Вам показывается кино" ); // (*)
// ...
}В коде выше, если
Результат функции с пустым или без него –
Если функция не возвращает значения, это всё равно, как если бы она возвращала
function doNothing() { /* пусто */ }
alert( doNothing() === undefined ); // trueПустой
function doNothing() {
return;
}
alert( doNothing() === undefined ); // trueНикогда не добавляйте перевод строки между и его значением
Для длинного выражения в
return
(some + long + expression + or + whatever * f(a) + f(b))Код не выполнится, потому что интерпретатор JavaScript подставит точку с запятой после
return;
(some + long + expression + or + whatever * f(a) + f(b))Таким образом, это фактически стало пустым
Если мы хотим, чтобы возвращаемое выражение занимало несколько строк, нужно начать его на той же строке, что и
return (
some + long + expression
+ or +
whatever * f(a) + f(b)
)И тогда всё сработает, как задумано.
Выбор имени функции
Функция – это действие. Поэтому имя функции обычно является глаголом. Оно должно быть кратким, точным и описывать действие функции, чтобы программист, который будет читать код, получил верное представление о том, что делает функция.
Как правило, используются глагольные префиксы, обозначающие общий характер действия, после которых следует уточнение. Обычно в командах разработчиков действуют соглашения, касающиеся значений этих префиксов.
Например, функции, начинающиеся с
"get…"– возвращают значение,"calc…"– что-то вычисляют,"create…"– что-то создают,"check…"– что-то проверяют и возвращают логическое значение, и т.д.
Примеры таких имён:
showMessage(..) // показывает сообщение
getAge(..) // возвращает возраст (получая его каким-то образом)
calcSum(..) // вычисляет сумму и возвращает результат
createForm(..) // создаёт форму (и обычно возвращает её)
checkPermission(..) // проверяет доступ, возвращая true/falseБлагодаря префиксам, при первом взгляде на имя функции становится понятным, что делает её код, и какое значение она может возвращать.
Одна функция – одно действие
Функция должна делать только то, что явно подразумевается её названием. И это должно быть одним действием.
Два независимых действия обычно подразумевают две функции, даже если предполагается, что они будут вызываться вместе (в этом случае мы можем создать третью функцию, которая будет их вызывать).
Несколько примеров, которые нарушают это правило:
getAge– будет плохим выбором, если функция будет выводитьalertс возрастом (должна только возвращать его).createForm– будет плохим выбором, если функция будет изменять документ, добавляя форму в него (должна только создавать форму и возвращать её).checkPermission– будет плохим выбором, если функция будет отображать сообщение с текстомдоступ разрешён/запрещён(должна только выполнять проверку и возвращать её результат).
В этих примерах использовались общепринятые смыслы префиксов. Конечно, вы в команде можете договориться о других значениях, но обычно они мало отличаются от общепринятых. В любом случае вы и ваша команда должны чётко понимать, что значит префикс, что функция с ним может делать, а чего не может.
Сверхкороткие имена функций
Имена функций, которые используются
очень часто
, иногда делают сверхкороткими.
Например, фреймворк
Это исключения. В основном имена функций должны быть в меру краткими и описательными.
Функции == Комментарии
Функции должны быть короткими и делать только что-то одно. Если это что-то большое, имеет смысл разбить функцию на несколько меньших. Иногда следовать этому правилу непросто, но это определённо хорошее правило.
Небольшие функции не только облегчают тестирование и отладку – само существование таких функций выполняет роль хороших комментариев!
Например, сравним ниже две функции
Первый вариант использует метку
function showPrimes(n) {
nextPrime: for (let i = 2; i < n; i++) {
for (let j = 2; j < i; j++) {
if (i % j == 0) continue nextPrime;
}
alert( i ); // простое
}
}Второй вариант использует дополнительную функцию
function showPrimes(n) {
for (let i = 2; i < n; i++) {
if (!isPrime(i)) continue;
alert(i); // простое
}
}
function isPrime(n) {
for (let i = 2; i < n; i++) {
if ( n % i == 0) return false;
}
return true;
}Второй вариант легче для понимания, не правда ли? Вместо куска кода мы видим название действия (
Таким образом, допустимо создавать функции, даже если мы не планируем повторно использовать их. Такие функции структурируют код и делают его более понятным.
Итого
Объявление функции имеет вид:
function имя(параметры, через, запятую) {
/* тело, код функции */
}- Передаваемые значения копируются в параметры функции и становятся локальными переменными.
- Функции имеют доступ к внешним переменным. Но это работает только изнутри наружу. Код вне функции не имеет доступа к её локальным переменным.
- Функция может возвращать значение. Если этого не происходит, тогда результат равен
undefined.
Для того, чтобы сделать код более чистым и понятным, рекомендуется использовать локальные переменные и параметры функций, не пользоваться внешними переменными.
Функция, которая получает параметры, работает с ними и затем возвращает результат, гораздо понятнее функции, вызываемой без параметров, но изменяющей внешние переменные, что чревато побочными эффектами.
- Имя функции должно понятно и чётко отражать, что она делает. Увидев её вызов в коде, вы должны тут же понимать, что она делает, и что возвращает.
- Функция – это действие, поэтому её имя обычно является глаголом.
- Есть много общепринятых префиксов, таких как:
create…,show…,get…,check…и т.д. Пользуйтесь ими как подсказками, поясняющими, что делает функция.
Функции являются основными строительными блоками скриптов. Мы рассмотрели лишь основы функций в JavaScript, но уже сейчас можем создавать и использовать их. Это только начало пути. Мы будем неоднократно возвращаться к функциям и изучать их всё более и более глубоко.






