Доброго времени суток, друзья!
В нашем прошлом уроке мы с Вами продолжили знакомство с функциями. Мы установили, что существуют Именованные функции и Анонимные функции, рассмотрели разницу между этими двумя видами функций. Разобрали способы вызова Анонимной функции через метод Присвоения и с помощью конструкции Самовызывающей функции. Кроме того, мы вывели некоторые правила, описывающие работу функций и рассмотрели все вышеперечисленное на практике.
Чтобы завершить тему Functions (Функции) (в разрезе основ JavaScript для абсолютных новичков), нам осталось рассмотреть всего несколько нюансов и чуточку теории. Но прежде, чем продолжать наши исследования в области оставшейся информации, я бы хотел сделать небольшое отступление в сторону профилирования.
Дело в том, что в прошлом уроке я несколько раз писал нечто вроде:
...выполнен уже не будет и приведет к ошибке...
или
... второй вызов никакого сообщения уже на выдал, потому как на самом деле привел к ошибке...
И уже после того как урок был опубликован, я понял, что все эти мои сообщения об ошибке в коде, для Вас никак не подтверждаются. То есть, я-то конечно понимаю, что какая-то часть кода приведет к ошибке, но для Вас этот момент всего лишь слова. Я думаю это положение дел надо исправить и показать Вам что за фразой "...потому как на самом деле привел к ошибке..." действительно располагается некая ошибка. Лишней эта информация не будет, а даже наоборот некоторые из наших практических опытов будут иметь более наглядные примеры, если мы с Вами будем в курсе того как их профилировать.
Урок 20. Профилирование. Функции, часть III.
Профилирование.
Что же это за слово такое мудреное профилировать? Если придерживаться наших традиций и не вдаваться в подробности официальной терминологии, то слово профилирование вполне можно воспринимать как сбор данных об ошибках в коде. Проверка так сказать на то, а все ли в порядке с нашим кодом? Особенно во время его исполнения.
Как мы можем собрать такие данные? На самом деле в любой современный браузер встроены специальные инструменты для профилирования программ (кода). Просто как пользователи мы пользуемся ими крайне редко, а вот разработчики с ними знакомы на ура. Итак, как нам до них добраться. В большинстве случаев добраться до инструмента профилирования нам поможет клавиша F12, если нажать ее в интересующем Вас окне браузера:
Если Вы используете Chrome, то увидите то же, что изображено на скриншоте. Если используете другой браузер - Вы увидите нечто подобное. Как можете видеть открывшееся окно имеет множество кладок и кнопок, но нас с Вами интересует ровно одна вкладка. Вот эта:
Я не стану описывать здесь все возможности работы с вкладкой Console, возможно со многими из этих возможностей мы познакомимся в процессе дальнейшего знакомства с JavaScript. На данном же этапе нам с Вами потребуется лишь одна функция этой вкладки - информативная.
Давайте запустим в браузере последний пример кода из предыдущего урока. Вот этот:
// Самовызывающаяся функция
(function message (text) {
alert(text);
})('привет, я самовызывающаяся функция!');
message('этот вызов исполнен уже не будет');
В прошлом уроке по этот код я писал, что вызов функции подчеркнутый зеленым исполниться, а вот второй вызов, где мы обращаемся к функции по имени - вызовет ошибку, так как сама функция была объявлена внутри самовызывающейся конструкции. Давайте с помощью вкладки Console посмотрим, действительно ли ошибка имеет право быть:
Теперь благодаря вкладке Console мы можем видеть, что первый вызов действительно отрабатывает, а попытка выполнить второй вызов кидает нам ошибку:
Оранжевой линией подчеркнут вид ошибки. Зелёной линией - суть ошибки (в данном случае он сообщает нам что обращение message undefined (неизвестно). И, наконец, синим подчеркнута ссылка с указанием файла и строки кода в этом файле, где возникла ошибка (в нашем случае это core.js и строка кода №7).
Теперь, когда мы пользоваться информативной частью вкладки Console, мы можем продолжать рассматривать тему Функций дальше.
Функции, часть III.
Функции в JavaScript'e способны не только выполнять какой-то определенный набор действий (в идеале полезный), но и возвращать некий результат. Результат выполнения какой-либо функции мы можем чему-нибудь присвоить или задействовать его в различных операциях межу переменными, ну или в каких-либо других операциях. Возращение результата внутри функции происходит благодаря оператору return (с английского можно перевести как "вернуть"). Давайте рассмотрим несколько практических примеров:
//Работа с оператором return
var c = 10;
var d = sum(5,5);
function message (text) {
alert(text);
}
function sum (a, b) {
return a + b;
}
message(c + d);
Давайте разбираться. Итак, у нас есть две Именованных функции. Первая - это уже знакомая нам функция message она выводит сообщения. Вторая функция имеет название sum. Как видим, она принимает два параметра и возвращает результат сложения этих параметров с помощью оператора return. Если мы обратимся с Вами к правилу о работе с Именованными функциями, то вспомним, что такие функции "всплывают" в самое начало кода (самый верх) перед непосредственным исполнением самого кода. То есть вызов функции sum на строке №4 не вызовет никакой ошибки. Сама запись var d = sum(5,5);
означает что в переменной d
окажется результат работы функции sum. Это произойдет именно благодаря записи return a + b;
. Нетрудно догадаться что результатом записи sum(5,5);
станет 10. И на строке №14 мы вызываем функцию message и передаём ей аргумент в виде суммы двух переменных c
и d
. Переменная c
имеет значение 10 с самого начала. Переменная d
получила свое значение в результате работы функции sum и тоже равна 10. Десять плюс десять будет равно двадцать. То есть, если подставить значения аргументов и произвести с ними расчеты, то запись вида message(c + d);
будет восприниматься JavaScript'ом как message(20);
. В итоге мы должны получить сообщение с надписью "20". Давайте проверим:
Как видим, это действительно так. Идем дальше. В примере выше мы использовали так называемое присвоение результат работы функции переменной. Но никто нам не запрещает использовать функцию сразу, без присвоения. Например, это можно сделать так:
//Работа с оператором return
var c = 10 + sum(5, 5);
function message (text) {
alert(text);
}
function sum (a, b) {
return a + b;
}
message(c);
Обратите внимание на то как видоизменился наш код. Мы полностью убрали переменную d
, и вместо этого сразу же напрямую используем функцию sum в вычислении значения для переменной c
, используя вот такую запись var c = 10 + sum(5, 5);
. Опять же, так как функция sum использует оператор return - она возвращает результат соей работы. Поэтому запись var c = 10 + sum(5, 5);
можно смело интерпретировать как запись var c = 10 + 10;
, что означает что в итоге в переменной с
окажется значение 20. Вызов message(c);
на строке №13 выведет сообщение идентичное сообщению из предыдущего примера.
Однако и это еще не все. Так как в функции sum используется return мы смело можем передавать вызов этой функции как аргумент для другой функции. Пример:
//Работа с оператором return
var c = 10;
function message (text) {
alert(text);
}
function sum (a, b) {
return a + b;
}
message(c + sum(5,5));
Обратите внимание. Теперь вызов функции sum передан непосредственно в аргумент функции message. И результатом такой записи будет сообщение всё с той же цифрой 20.
Подводя итог эти трем примерам моно сделать вывод:
Когда во взаимодействиях между переменными участвует вызов функции, которая использует оператор return и должна возвращать значение, то сначала выполниться эта функция (чтобы получить результат для возвращения), а уже после этого будут выполнятся другие операции взаимодействия.
И на последок, давайте начнем более глубоко разбирать тему Функций в отношении их аргументов. В предыдущих уроках мы использовали несколько способов вызова функций:
- просто вызов, без аргументов -
message();
- вызов с одним аргументом -
message('привет голос');
- вызов с несколькими аргументами -
sum(5, 5);
Возникает вопрос, а что именно мы можем передавать в аргументы, и сколько таких аргументов мы можем использовать?
Начнем с последней части. В JavaScript'e нет ограничения по количеству использования аргументов функции. То есть теоретически Вы можете создавать функции с бесконечным числом аргументов. То есть что-то типа такого...
...имеет право на жизнь. Правда в таком случае возникает вопрос удобочитаемости кода. По, для справки, можно сказать что негласно считается, что в правильно написанном коде должны использоваться функции с числом аргументов не более четырёх. Если же аргументов в функции ожидается больше, принято использовать немного ругой подход, который мы рассмотрим с вами после изучения темы Объекты.
Что же касается вопроса - "а что именно мы можем передавать в аргументы?" То этот вопрос немного сложнее и на него мы ответим в нашем следующем уроке.
А на сегодня все.
Ссылки на предыдущие уроки:
(function () {
Урок 1, Урок 2, Урок 3, Урок 4, Урок 5, Урок 6, Урок 7, Урок 8, Урок 9, Урок 10, Урок 11, Урок 12, Урок 13, Урок 14, Урок 15, Урок 16, Урок 17, Урок 18, Урок 19 })();
Привет!
Этот пост был выбран Академией Голоса и попал в список программы поддержки качественных образовательных постов.
Ссылка на твой пост будет опубликована в отчете Академии.
Спасибо за полезный контент (ノ◕ヮ◕)ノ*:・゚✧
@rassen, Поздравляю!,
Ваш пост был упомянут в моем хит-параде в следующей категории:
Привет!
Я тут добавил ещё одно слагаемое бессознательно понимая, что я получу на выходе. Работает.
Но я не понимаю работу оператора return, а именно, что стоит за словом он "возвращает". Откуда именно он что берёт и куда именно вставляет (возвращает). Как function sum (a, b, e) {
return a + b + e;} понимает, что за "а,b,е" стоят пятёрки?
Каким образом он видит, верней на каком шаге скрипт обращаеся к var d = sum(5,5,5); и считывает оттуда пятёрки?
var c = 10;
var d = sum(5,5,5);
function message (text) {
alert(text);
}
function sum (a, b, e) {
return a + b + e;
}
message(c + d);
Спасибо.
Смотрите, когда вы объявляете(создаете) функцию вы этим действием как бы подготавливаете шаблон
Вот для наглядности я накидал код который вы привели в вопросе.
Воспринимайте запись
как шаблон для работы функции message. Теперь обратите внимание на стрелки. Видите порядок букв в "шаблоне" вашей функции, совпадает с порядком цифр в вызове
message (1, 2, 3);
В этом и состоит ответ на Ваш вопрос:JavaScript берет ваш вызов
message (1, 2, 3);
и сравнивает его с вашим "шаблоном"function message (a, b, c)
и по соответствующему порядку присваивает значения аргументов: a = 1, b = 2, c = 3 соответственно, а затем производит с ними операции.Теперь касательно return. Смотрите, в наших уроках мы испоьзовали функцию
Эта функция просто исполняет код писанный внутри - выводит сообщение. Она не делает никаких вычислений и не дает никакого фиксированного результата. Она просто исполнила действие и все.
Если мы напишем что-то вроде:
то в переменную
d
у нас ничего не сохранится. ее значение будет неопределенным - undefined.Если же мы рассматриваем функцию с оператором return. Вот такую:
То самим вот этим словом return мы как бы говорим функции: "ВЕРНИ на место своего вызова, результат своей работы". Таким образом запись
var a = sum(1, 2);
можно воспринимать как записьvar a = 3
. 3 в данном случае это результат работы функции sum. И вот именно благодаря return на место вызоваsum(1, 2);
и возвращается этот результат. То же самое происходит в случае какой-то операции например сложения.Функция sum использует оператор return и ВЕРНЁТ на место своего вызова результат сложения 1 и 2. И запись вверху мжно будет воспринимать как: