что такое функция литерал
Функции и функциональные литералы
Функция –это фрагмент исполняемого кода, который определен в JavaScript-программе или заранее предопределен в реализации JavaScript. Хотя функция определяется только один раз, JavaScriptпрограмма может исполнять или вызывать ее сколько угодно. Функции могут передаваться аргументы, или параметры, определяющие значение или значения, для которых она должна выполнять вычисления; также функция может возвращать значение, представляющее собой результат этих вычислений. Реализации JavaScript предоставляют много предопределенных функций, таких как функция Math.sin(), возвращающая синус угла.
JavaScript-программы могут также определять собственные функции, содержащие, например, такой код:
function square(x) //Функция называетсяsquare. Она принимает один аргумент, x.
return x*x; // Функция возводит свой аргумент в квадрат и возвращает
> // Здесь функция заканчивается.
Определив функцию, можно вызывать ее, указав имя, за которым следует заключенный в скобки список необязательных аргументов, разделенных запятыми. Следующие строки представляют собой вызовы функций:
d = compute_distance(x1, y1, z1, x2, y2, z2);
Важной чертой JavaScript является то, что функции представляют собой значения, которыми можно манипулировать в JavaScript-коде. Во многих языках, в том числе в Java, функции – это всего лишь синтаксические элементы языка, но не тип данных: их можно определять и вызывать. То обстоятельство, что функции в JavaScript представляют собой настоящие значения, придает языку большую гибкость. Это означает, что функции могут храниться в переменных, массивах и объектах, а также передаваться в качестве аргументов другим функциям.
Поскольку функции представляют собой значения, такие же, как числа и строки, они могут присваиваться свойствам объектов. Когда функция присваивается свойству объекта, она часто называется методом этого объекта. Методы – важная часть объектно-ориентированного программирования.
Функции
Функциональные литералы
Функциональный литерал задается с помощью ключевого слова function, за которым следуют необязательное имя функции, список аргументов функции, заключенный в круглые скобки, и тело функции в фигурных скобках. Другими словами, функциональный литерал выглядит так же, как определение функции, правда, у него может не быть имени. Самое большое различие состоит в том, что функциональные литералы могут входить в другие JavaScript-выражения. То есть функцию square()не обязательно задавать в виде определения:
Ее можно задать с помощью функционального литерала:
var square = function(x)
Имеется еще один способ определения функции: можно передать список аргументов и тело функции в виде строк в конструктор Function(). Например:
var square = new Function(«x», «return x*x;»);
Такое определение функций используется редко.
Объекты
Объект –это коллекция именованных значений, которые обычно называют свойствами(properties) объекта.
Создание объектов
Объекты создаются путем вызова специальных функций-конструкторов. Все следующие строки создают новые объекты:
var pattern = new RegExp(«\\sjava\\s», «i»);
Создав собственный объект, можно его как угодно использовать и устанавливать его свойства:
var point = new Object();
Объектные литералы
В JavaScript определяется синтаксис объектных литералов, позволяющий создавать объекты и указывать их свойства. Объектный литерал (также называемый инициализатором объекта) представляет собой список разделенных запятыми пар «свойство/значение», заключенный в фигурные скобки. Внутри пар роль разделителя играет двоеточие. Таким образом, объект pointиз предыдущего примера также может быть создан и инициализирован следующей строкой:
Объектные литералы могут быть вложенными. Например:
Наконец, значениями свойств в объектных литералах не обязательно должны быть константы – это могут быть произвольные JavaScriptвыражения. Кроме того, в качестве имен свойств в объектных литералах допускается использовать строковые значения:
Массивы
Массив (array), как и объект, представляет собой коллекцию значений. Если каждое значение, содержащееся в объекте, имеет имя, то в массиве каждое значение имеет номер, или индекс. В JavaScript можно извлекать значения из массива, указав после имени массива индекс, заключенный в квадратные скобки. Например, если a– это имя массива, а i– неотрицательное целое число, то a[i] является элементом массива. Индексы массива начинаются с нуля, т. е. a[2] ссылается на третий элемент массива a. Массивы могут содержать любой тип данных JavaScript, в том числе ссылки на другие массивы или на объекты или функции. Например:
Этот код ссылается на свойство widthобъекта, хранящегося во втором элементе массива, в свою очередь хранящегося в свойстве imagesобъекта document. Следует также отметить, что в JavaScript не поддерживаются многомерные массивы (хотя допускается существование массивов из массивов). И наконец, поскольку JavaScript является не типизированным языком, поэтому элементы массива не обязательно должны иметь одинаковый тип.
Создание массивов
Массив может быть создан с помощью функции-конструктора Array(). Созданному массиву допустимо присваивать любое количество индексированных элементов:
Массивы могут также быть инициализированы путем передачи элементов массива конструктору Array(). Таким образом, предыдущий пример создания и инициализации массива можно записать так:
var a = new Array(1.2, «JavaScript», true, < x:1, y:3 >);
Если передать конструктору Array()только одно число, оно определит длину массива. Таким образом, следующее выражение создает новый массив с 10 неопределенными элементами:
var a = new Array(10);
Литералы массивов
Программный код, создающий и инициализирующий массив из предыдущего раздела, можно записать следующим образом:
var a = [1.2, «JavaScript», true, < x:1, y:3 >];
Как и объектные литералы, литералы массивов могут быть вложенными:
var matrix = [[1,2,3], [4,5,6], [7,8,9]];
Как и в объектных литералах, элементы в литерале массива могут быть произвольными выражениями и не обязательно должны быть константами:
var table = [base, base+1, base+2, base+3];
Для того чтобы включить в литерал массива неопределенный элемент, достаточно пропустить значение между запятыми. Следующий массив содержит пять элементов, в том числе три неопределенных:
var sparseArray = [1. 5];
Заданные значения
Значение null
Ключевое слово nullв JavaScript имеет специальный смысл. Обычно считается, что у значения nullобъектный тип и оно говорит об отсутствии объекта. Значение nullуникально и отличается от любых других. Если переменная равна null, следовательно, в ней не содержится допустимого объекта, массива, числа, строки или логического значения.
Значение undefined
Специальное значение, иногда используемое в JavaScript, – undefined. Оно возвращается при обращении либо к переменной, которая была объявлена, но которой никогда не присваивалось значение, либо к свойству объекта, которое не существует. Заметьте, что специальное значение undefined– это не то же самое, что null. Хотя значения nullи undefinedне эквивалентны друг другу, оператор эквивалентности ==считает их равными. Рассмотрим следующее выражение:
Однако когда действительно требуется отличить значение nullот значения undefined, нужен оператор идентичности === или оператор typeof
Объект Date
Значения даты и времени не относятся к этим фундаментальным типам, однако в JavaScriptимеется класс объектов, представляющих дату и время, и этот класс можно использовать для работы с этим типом данных. Объект Dateв JavaScript создается с помощью оператора new и конструктора Date():
var now = new Date(); // Создание объекта,в котором хранятся текущие дата и время.
// Создание объекта, в котором хранится дата Рождества.
// Обратите внимание: номера месяцев начинаются с нуля, поэтому декабрь имеет номер 11!
var xmas = new Date(2000, 11, 25);
Регулярные выражения
Регулярные выражения предоставляют богатый и мощный синтаксис описания текстовых шаблонов. Они применяются для поиска соответствия заданному шаблону и реализации операций поиска и замены. В JavaScript для формирования регулярных выражений принят синтаксис языка Perl.
Регулярные выражения представляются в JavaScript объектом RegExpи могут создаваться с помощью конструктора RegExp(). Как и объект Date, объект RegExp не является одним из фундаментальных типов данных JavaScript; это лишь стандартизованный тип объектов, предоставляемый всеми соответствующими реализациями JavaScript. Однако в отличие от объекта Date, объекты RegExpимеют синтаксис литералов и могут задаваться непосредственно в коде JavaScript-программы. Текст между парой символов слэша образует литерал регулярного выражения. За вторым символом слэша в паре могут также следовать одна или несколько букв, изменяющих смысл шаблона.
Что такое литерал функции в Scala?
Что такое литерал функции в Scala и когда я должен использовать их?
Функция литерал-это альтернативный синтаксис определения функции. Это’ы полезно, когда вы хотите передать функцию в качестве аргумента для метода (особенно высшего порядка, как сложить или фильтр, работа), но вы не’т хотите, чтобы определить отдельную функцию. Функции литералы являются анонимными, они не’т иметь имя по умолчанию, но вы можете дать им имя, привязывая их к переменной. Литерал функции определяется так:
Вы можете привязать их к переменным:
Как я уже говорил, функции литералы используются для передачи в качестве аргумента функции высшего порядка. Они’re также полезны для определения остроты или вспомогательные функции внутри других функций.
Тур Скала дает довольно хорошую ссылку для функции литералы (они называют их анонимными функциями).
Это могло бы быть полезно сравнить функции литералы с другими видами литералы в Scala. Литералы являются нотационной сахара представление значения некоторые типы языка считают особенно важным. [Скала] так2 целочисленные литералы символьные литералы строковые литералы и т. д. Скала рассматривает функции как первого класса представимых значений в исходный код функции литералы. Эти значения функция населяют специальные функция. Например,
Литералы часто используются в качестве анонимных ценностей, то есть, без привязке к имени переменной первой. Это помогает сделать программу более лаконично и уместно, когда литерал не предназначены для повторного использования. Например:
4.13 – Литералы
В программировании константа – это фиксированное значение, которое нельзя изменять. В C++ есть два типа констант: литеральные константы и символьные константы. В этом уроке мы рассмотрим литеральные константы, а в следующем – символьные константы.
Литеральные константы (обычно называемые просто литералами) – это значения, вставленные непосредственно в код. Например:
Они являются константами, потому что их значения не могут быть изменены динамически (сначала вы должны изменить их, а затем перекомпилировать программу, чтобы изменение вступило в силу).
Так же, как у объектов есть тип, тип есть и у всех литералов. Тип литерала предполагается из значения и формата самого литерала.
Суффиксы литералов
Если тип литерала по умолчанию не соответствует необходимому, вы можете изменить тип литерала, добавив суффикс:
Обычно вам не нужно использовать суффиксы для целочисленных типов, но вот пара примеров:
Начинающие программисты часто не понимают, почему следующий код работает не так, как ожидалось:
Литералы можно использовать в коде C++, если их значения понятны. Чаще всего это происходит при использовании для инициализации или присвоения значения переменной, выполнения математических операций или вывода текста на экран.
Строковые литералы
В уроке «4.11 – Символы» мы определили строку как набор последовательных символов. C++ поддерживает строковые литералы:
Экспоненциальная запись для числовых литералов с плавающей запятой
Есть два разных способа объявить литералы с плавающей точкой:
Во второй форме число после экспоненты может быть отрицательным:
Литералы в восьмеричной и шестнадцатеричной системах счисления
В повседневной жизни мы считаем, используя числа в десятичной системе счисления, где каждая цифра может быть 0, 1, 2, 3, 4, 5, 6, 7, 8 или 9. Десятичная система счисления число также называется «с основанием 10», потому что в ней возможно использование 10 цифр (от 0 до 9). В этой системе мы считаем так: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,… По умолчанию, числа в программах на C++ считаются десятичными.
В двоичной системе счисления всего 2 цифры: 0 и 1, поэтому она называется «с основанием 2». В двоичном формате мы считаем так: 0, 1, 10, 11, 100, 101, 110, 111,…
Существуют две других системы счисления, которые иногда используются в вычислениях: восьмеричная и шестнадцатеричная.
Восьмеричная система счисления – с основанием 8, то есть доступны только цифры: 0, 1, 2, 3, 4, 5, 6 и 7. В восьмеричном формате мы считаем так: 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12,… (примечание: цифр 8 и 9 нет, поэтому мы сразу переходим от 7 к 10).
Десятичная система | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Восьмеричная система | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 |
Чтобы использовать литерал в восьмеричном формате, добавьте к вашему литералу префикс 0 (ноль):
Эта программа печатает:
Почему 10, а не 12? Потому что числа печатаются в десятичном формате, а 12 в восьмеричном формате = 10 десятичном формате.
Восьмеричная система счисления практически не используется, и мы рекомендуем вам ее избегать.
Десятичная система | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Восьмеричная система | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 | 11 |
Эта программа печатает:
Поскольку для одной шестнадцатеричной цифры возможны 16 различных значений, мы можем сказать, что одна шестнадцатеричная цифра использует 4 бита. Следовательно, пара шестнадцатеричных цифр может использоваться для точного представления полного байта.
До C++14 не было возможности назначить литерал в двоичном формате. Однако шестнадцатеричные пары предоставляют нам для этого полезный обходной путь:
Литералы в двоичном формате и разделители цифр C++14
В C++14 мы можем назначать литералы в двоичном формате с помощью префикса 0b :
Поскольку длинные литералы трудночитаемы, в C++14 также добавлена возможность использования кавычек ( ‘ ) в качестве разделителя цифр.
Если ваш компилятор несовместим с C++14, он пожалуется, если вы попытаетесь использовать любой из этих приемов.
Печать десятичных, восьмеричных, шестнадцатеричных и двоичных чисел
Эта программа печатает:
Эта программа напечатает:
Мы также можем создать временный (анонимный) std::bitset для печати одного значения. В приведенном выше коде эта строка:
Магические числа, и почему это плохо
Рассмотрим следующий фрагмент:
Число, такое как 30 в приведенном выше фрагменте, называется магическим числом. Магическое число – это литерал (обычно число) в середине кода, не имеющий никакого контекста. Что значит 30? Хотя вы, наверное, догадываетесь, что в данном случае это максимальное количество студентов в классе, но это не совсем очевидно. В более сложных программах может быть очень сложно сделать вывод, что представляет собой жестко запрограммированное число, если нет комментария, объясняющего его.
Использование магических чисел обычно считается плохой практикой, потому что, помимо отсутствия контекста, для чего они используются, они создают проблемы, если значение необходимо изменить. Предположим, школа покупает новые парты, позволяющие увеличить количество учеников в классе с 30 до 35, и наша программа должна это отразить. Рассмотрим следующую программу:
Хотя мы говорим «магические числа», это относится ко всем видам значений. Рассмотрим следующий пример:
В этом примере только одно число (100), но оно также используется в строках. Если мы решим обновить максимальное количество, скажем, на 200, нам придется обновить три разных случая, где встречается 100.
К счастью, существуют лучшие варианты (символьные константы). Об этом мы поговорим на следующем уроке.
Лучшая практика
Не используйте магические числа в своем коде.
ВИДЕОУРОК №5. Функции
Доступ к полному курсу с учебными материалами и тестированием на 30 дней за 9.99 USD
Вступление. Функции
Создание функций
Пример, функция принимает аргумент
Пример оператора return
Использование нескольких аргументов
Области видимости
Примеры, области видимости
Рекурсивный вызов
Функция – литерал
Вложенные функции
CallBackFunction
Вы действительно хотите открыть доступ к тестированию по курсу JavaScript Стартовый 2015 на 40 дней?
Функции – это блок кода, который можно многократно вызывать для выполнения. Функция может принимать аргументы и возвращать значения. Я думаю, что многие из слушателей этого видеокурса сталкивались с такими понятиями как функции и процедуры. На всякий случай давайте мы попробуем еще раз с самого начала объяснить и понять, как работают функции, какое их назначение в программном коде. Функция по сути является основным строительным блоком любого приложения. Если вы посмотрите на этот слайд, то вот этот прямоугольник посредине слайда, он у нас символизируем функцию, то есть это некий черный ящик. Мы даем ему какую-то информацию на вход, в этом черном ящике происходят какие-то операции и что-то появляется на выходе, какой-то результат. Вот получается, мы в функцию передаем сейчас, вот эта иконка символизирует у нас один байт информации, вот со значением один в двоичной системе исчисления. Вот мы в функцию передали это значение, вот эти колесики, они символизируют какие-то действия, происходящие внутри функции, то есть функция произвела какие-то вычисления, что-то произошло с этим значением, и в итоге функция на выход дала какое-то новое значение. Бывают функции, которые принимают данные и выдают какой-то результат. Бывают функции, которые ничего не принимают и выдают какой-то результат. Бывают функции, которые ничего не принимают и ничего не выдают. Бывают функции, которые что-то принимают, но ничего не возвращают. То есть, есть несколько разновидностей функций, мы сейчас их в коде всех с вами разберем. Но перед тем, как переходить к коду, давайте попробуем понять назначение функций на каком-нибудь простом, жизненном примере. Представьте, что вам, в вашем приложении нужно описать процесс заварки чая. Вам нужно будет в JavaScript сценарии несколько раз в разных частях программы вашей выполнять заварку чая. Из чего состоит заварка чая? Первое – нужно пойти на кухню. Второе – нужно взять чашку и засыпать туда сахар и чай. Третья операция – закипятить воду. Четвертая – залить воду в чашку. Вот 4 операции и чай готов. Если вам нужно в вашем приложении чай заваривать 10 раз, вот вам придется в 10 разных частях программы вызвать 4 инструкции для того, чтобы заварить чай. При этом вам нужно следить, чтобы вы не напутали с последовательностью инструкций, потому что если вы в начале зальете воду, потом закипятите ее, это уже будет не совсем чай, неправильно он будет сделан. Получается, что в тех ситуациях, когда у нас есть несколько инструкций, какой-то блок кода, который повторяется в разных частях программы, вот этот блок кода можно превратить в функцию. Например, вот эти 4 инструкции, для заварки чая, их можно вынести в функцию и дать функции имя «Заварить чай». А те части программы, в которых мы раньше пытались заваривать чай, используя 4 инструкции, 4 команды последовательные, вот эти 4 команды можно удалить и вместо них установить запуск функции «заварка чая». Я верю, что после просмотра примеров, назначение функций всем будет понятней.
Давайте сейчас посмотрим второй слайд, посмотрим, как именно функция определяется в JavaScript коде, потом перейдем в Visual Studio и посмотрим на несколько первых примерах. Когда мы хотим определить в коде функцию, первое, что мы должны сделать – это использовать специальное ключевое слово. Слова function. Наличие этого слова в коде указывает, что мы сейчас создаем новую функцию, или объявляем функцию. После слова function в большинстве случаев следует имя. В некоторых ситуациях имя не указывается, мы рассмотрим такие варианты функций, но сейчас на слайде вы видите, что сразу после function, тут же идет фраза, литерал, который будет указывать имя функции, обычно функцию называют не так, как на нашем слайде, myFunction – это имя, которое ничего не означает. По имени не можем понять, а что именно делает функция. Хорошее имя для функции – это глагол, описывающею что именно функция будет выполнять, когда мы ее вызовем. Например, функция будет называются getUserName. Сразу же понятно назначение функции. Если мы ее запустим, то она отдаст нам имя пользователя. Или спросит имя у пользователя, или спросит имя у пользователя, или получит его с каких-то внутренних переменных. Другой вариант функции – Calculate, CalculateSum, например, то есть посчитать сумму. Понятно, что если мы эту функцию запустим, то получим сумму каких-то значений. После имени функции, у нас установлены параметры, параметры – это то, что функция принимает для обработки. Если нашей функции при запуске необходимы какие-то значения, эти значения функции могут быть переданы с помощью параметров. Подробней с параметрами мы познакомимся с вами уже в примерах.
Давайте сейчас посмотрим первые примеры использования функции в Visual Studio. Значит, как мы уже посмотрели на слайдах, определение функции всегда начинается с ключевого слова function. Вот на строке 21 мы создаем функцию, создаем приложение, создаем строительный блок, который будем потом неоднократно использовать. Мы указали ключевое слово, далее мы указали имя функции – MyFirstFunction(). Так как эта функция не принимает никаких входящих данных, она не должна производить расчеты над какими-то значениями, мы просто после имени ставим круглые скобочки. Это означает, что функция не принимает никаких параметров. И далее в теле функции мы выполняем три инструкции, в тело документа выводим сообщение «Hello from MyFirstFunction!, How are you?, Goodbye!». Вот эти три строчки появляться в документе если мы запустим эту функцию. Мы сейчас просто создали функцию, то есть это просто заготовка, которую потом нужно вызвать, выполнить. Получается, когда интерпретатор, когда браузер дойдет до 21 строки. Существует такая функция, он не будет выполнять этот код, потому что определение функции, это просто создание инструкций, которые в будущем кто-то начнет использовать. Так же в нашем примере есть еще одна функция, на 27 строке, эта функция называется MySecondFunction(), и она выводит только одно сообщение «Hello from MySecondFunction!». Это все что она делает. Точно так же, как и предыдущая функция, это всего лишь объявление. То есть это блок кода, который не будет выполнятся до тех пор, пока мы не обратимся к функции и не запустим ее, не вызовем функцию. Значит 21-22 строка – мы объявили функцию. Теперь как мы этими функциями пользуемся. 33 строчка. Мы берем имя функции MyFirstFunction() уже без ключевого слова function, только имя и круглые скобочки. Когда мы используем такой синтаксис – имя функции + ее параметры, это означает, что мы обращаемся к функции и вот на строе 33, как только мы выполним эту операцию, это означает, что с 33 строки мы перепрыгиваем на строку 21. Выполняем инструкции на 22, 23, 24 строчке, и потом, когда мы эти инструкции до конца выполняем, мы возвращаемся обратно, перепрыгиваем на 33 строку и продолжаем выполнять инструкции, которые идут вот в этой части кода. Выполняем 35 строчку, вводим горизонтальную линию. Потом на 37 строчке мы видим, что мы взываем вторую функцию MySecondFunction(). То есть на 37 строке мы прыгаем на строчку 27, заходим в тело функции, вот операторные скобки, выполняем инструкцию, которая здесь заложена. Как только мы до конца выполняем все инструкции, заложенные в функции, мы возвращаемся обратно в ту точку, где функция изначально была запущена. Давайте попробуем проверить, что получится. Вот вы видите, первый раз мы на 33 строке вызвали функцию и отобразились те сообщения, которые заложены внутри этой функции, вот все эти инструкции, код весь этот выполнился. Потом 35 строчка, мы вывели горизонтальную линию. И строка 37 мы еще раз запустили функцию, уже вторую функцию и вот увидели ее результат. Если мы хотим несколько раз повторить вот этот блок кода, несколько раз вывести эти три сообщения, можем взять и просто продублировать вызов функции. Вот мы сейчас три раза запускаем MyFirstFunction(), то есть в приложении, на 33 строке мы пригнем на строку 21, выполним все что заложено в функции, вернемся обратно сюда. Перейдем на 34 строчку и увидим, что на ней опять происходит вызов функции. На 34 строке мы пригнем на 21 строчку, выполним все, что заложено в функцию и вернемся обратно на 34. На 35 опять пригнем в функцию, выполним все, что заложено и вернемся на 35. То есть каждый раз, когда мы вызываем функцию, мы производим переход в другую часть программы, выполняем инструкции, заложенные в этой другой части программы и возвращаемся обратно, где функция была изначально запущена. Давайте сейчас запустим и проверим, первый раз вызвалась наша функция, второй раз и третий раз. Вот пример, который я приводил с заваркой чая. Вместо того, чтобы здесь дублировать инструкции заварки чая, мы эти инструкции вынесли в отдельную функцию и каждый раз, когда нам хочется чая, мы берем и запускаем функцию сделать чай и не задумываемся о тех шагах, которые нужно выполнить, для того, чтобы появилась чашка чая. Перед тем, как переходить к следующим примерам, хочу, чтобы мы еще посмотрели, как можно пользоваться отладчиком и посмотреть, как функции работают именно под отладчиком. Лично мне удобней пользоваться отладчиком, который работает в Google Chrome, но как мы уже разбирали на прошлых уроках, если вы возьмете Firefox, например, с установленными Fireback флаером, или Internet Explorer, или Opera, во всех современных браузерах есть инструменты разработчика, поэтому просто выберете тот браузер, которым вам пользоваться нравится больше всего и в нем попробуйте разобраться с инструментами разработчика. Если мы сейчас запустим этот пример, в Chrome, если мы нажимаем на F12 в браузере это открывает панель разработчика. Вот панель разработчика, нас интересует сейчас вкладочка source. Вот когда вы впервые запустите свое приложение, вы увидите, что вот на этой вкладочке ничего нету, будет пусто, никаких исходных кодов текущего документа отображаться не будет. Если нажать по этой кнопочки showNavigator, то вы увидите те сценарии, которые доступны сейчас в текущем документе. Мы выбираем сейчас сам HTML документ, переходим в его исходный код, находим интересующею для нас функцию, вот мы хотим начать отладку с 33 строки. Ставим здесь breakpoint. Мы на прошлых занятиях разбирали с вами что такое breakpoint. Поставили breakpoint. Для того, чтобы теперь этот breakpoint сработал, чтобы эта точка остановила код и показала нам пошаговое выполнение скрипта, мы можем сейчас обновить страницу, видите сейчас вот это синий блок, красная стрелочка, которая находится рядом с ним, эта стрелочка символизирует ту часть кода, которую сейчас браузер выполняет. Вот сейчас мы возьмем с вами и если будем нажимать на кнопку F10 или на эту иконку, это означает, что мы переходи пошагово, построчно. Просто выполняем все инструкции. Если мы будем нажимать на кнопку F11 или на эту иконку, это будет означать, что при вызове функции мы будем переходить внутрь функции и смотреть, что будет происходить в самой функции. Вот если мы сейчас нажмем на F11, так как вот здесь мы взываем функцию myFunction, мы должны перейти внутрь функции, выполнить весь код, который находится в функции и вернутся обратно на 33 строчку. Давайте попробуем. Нажимаем на F11, видите мы попали внутрь функции, на строчку 22. Нажимаем еще раз F11, еще раз, и вот когда мы закончим операцию на 24 строке, мы вернемся в ту часть кода, в которой функцию изначально вызвали. Нажимаем еще раз F11 и вот видите мы вернулись на строчку 34 из-за функции, которую изначально запустили. Если сейчас еще раз нажать F11. Так как на 34 строке опять запускается функция, мы вернемся в тело функции и выполним то что находится в теле функции. Нажимаем F11, попадаем в функцию, выполняем код, который заложен в функции, видите, код у нас выводится сразу же в самом документе по мере его выполнения, выполнили функцию, вернулись в ту часть кода, где функция запускалась. Следующая функция, нажимаем F11, попадаем в тело функции, и вот так далее. Вот если вы не понимаете, как работает сценарий, если вы хотите найти ошибки в сценарии, рекомендую пользоваться отладчиком, он всегда помогает сэкономить время и быстро найти ту часть кода, с которой что-то у вас работает некорректно.
В следующем примере мы увидим, как в функции можно использовать переменные, которые доступны в области видимости, глобальной области видимости. Подробней о областях видимости мы сейчас с вами поговорим, а вот пока разберем данный пример. То есть в этом примере мы разберем, что функции могут работать с переменными в своем теле. Сейчас у нас есть 2 функции, на 22 строчке ask и на 28 функция say. То есть «спросить» и «сказать». Функция ask будет запускать ряд prompt функций, то есть функция prompt, это функция, которая уже определена в браузере. То есть если вот эта функция, это основная функция, то функция prompt находится где-то в браузере, задача этой функции показать диалоговое окошко, получить от пользователя данные, обработать эти данные и вернуть в наше приложение, вернуть нашему сценарию уже. Если кто-то запустит функцию ask в нашем коде, то вначале мы получим от пользователя имя, потом фамилию, потом возраст. И эти полученные данные запишем в переменную name, sname и age. Переменные, которые мы используем в функции ask обвялены выше, на 18, 19, 20 строчке. Вот эти переменные объявлены здесь и соответственно они могут быть использованы как внутри функции ask, так и внутри функции say. Видите, что функция say будет последовательно отображать вначале имя, потом фамилию, потом возраст и выводить эту информацию в тело документа. Но как мы уже с вами обсуждали, определение функции не значит, что эти функции будут работать, просто определив функцию, мы определили строительный блок в нашем приложении. Тут этот строительный блок должен использовать, для того чтобы код в функции запустился. И вот на 37 строке мы первый раз вначале запускаем функцию ask, чтобы попросить пользователя заполнить значениями переменные. А второй раз на 38 строчке мы запускаем функцию say, чтобы значения, которые находятся в переменных отобразились пользователю на экран. Давайте запустим пример и проверим. Первое – введите свое имя, фамилию и возраст. Вот значения, которые мы ввели в поля ввода, вот они отобразились у нас на экране.
В следующем пример мы посмотрим, как можно сделать так, чтобы функция требовала, чтобы одни параметры обязательно к ней были заданы, а другие параметры были опциональны. Вот сейчас на 15 строчке мы хотим сделать так, чтобы функция print принимала два аргумента. Первый аргумент- был обязательно, а второй аргумент, если его не предоставят, то функция возьмет свое какое-то значение по умолчанию. Задача функции print отображать в документе несколько сообщений, сообщений, которые были переданы первому аргументу. Вот если кто-то запускает эту функцию, первое, что делает функция – это 17 строчка. Проверят было ли предоставлено значение в параметр count. Если count равен undefined, то строка 18 мы говорим, что count будет равен значению три. То есть по умолчанию у нас всегда функция принт будет с count равен трем. Но если при запуске сюда передать значение, то на 17 строке условие не срабатывает и count будет равен тому значению, которое передал пользователь при вызове. Дальше после проверки на 21 строке мы запускаем цикл фор на количество итераций, равной значению переменной count. То есть count раз, на 22 строчке мы выводим сообщение переменной msg, то есть message. А в конце, когда все это заканчивается на 25 строке мы выводим horizontalRool. Вызов функции на 31 строчке, мы вызываем функцию только с один значение, со значением Hello, это значение первое, соответственно оно адресовано первому аргументу, переменной msg. НА 31 строке мы увидим, что сообщение Hello отобразится три раза, потому что count по умолчанию будет равен трем. На 32 строке, когда мы вызываем print двумя параметрами, двумя значениями world и семь. Это означает, что msg будет world, count будет равен семи. Соответственно условие не срабатывает и цикл срабатывает семь раз со значением, которое ввел пользователь. Hello три раза в соответствии со значением по умолчанию, world – семь раз. Вот этот пример показывает, как можно создать функцию и определить в функции опциональные параметры, которые не обязательны при запуске. Очень часто разработчики, которые создаю функцию с функциональными параметрами, добавляют вот такой комментарий, просто пишут необязательный параметр, или опциональный параметр для того, чтобы было понятно, что эта переменная, этот аргумент, он не обязательный при вызове. Все функции, которые мы сейчас с вами посмотрели, по сути они были процедурами, вот если вы работали с другими языками программирования, то вы сталкивались с таким термином как функция и процедура. Функция – это конструкция, блок кода, который мы запускаем, блок кода что-то делает, а потом возвращает нам результат. А процедура – это такой же блок кода, который мы запускаем, что-то происходит в этом блоке кода, но в результате ничего нам как клиентам этого блока кода, как запускающей стороне, нам никакой результат е возвращается. Вот мы с вами видели, что все наши примеры, в этих примерах функции не возвращали никаких данных в ответ. Мы их запустили, а в ответ ничего не получили. На самом деле в JavaScript нет такого понятия как процедуры, потому что любая функция всегда возвращает нам значение. Вот сейчас, у нас у всех примерах любая функция всегда возвращала значение undefined, просто мы им не пользовались и его игнорировали. Но запомните, что любая функция, если она не возвращает явно никаких данных, она вернет значение undefined. Давайте сейчас поострим как можно сделать функции, которые будут возвращать то что они рассчитали, то что они выполнили по окончанию своей работы.
Вот в следующем №6 примере мы посмотрим, как используется ключевое слово return и что оно делает. На строке 16 мы объявляем функцию sum, которая будет суммировать два входящих параметра «а» и «б». Но мы хотим сделать так, что функция, получив значение и посчитав сумму, не выводила сразу же результат в тело документа, а возвращала результат, которой получила. Мало ил как мы захотим с этим результатом работать, может мы не хотим его отображать в документе, может мы alert вывести, или мало что можно еще делать. Для того, чтобы функция просто вернула результаты своей работы, на 17 строке мы используем ключевое слово return, и после этого слова указываем то значение, которое функция должна будет вернуть после своей работы. Если запустить функцию sum, она у нас выполнит вычисления, отдаст результат своих исчислений, отдаст сумму двух входящих параметров. Вот когда мы пользуемся такими функциями, строка 20, нам необходимо использовать функции вот в таком ключе, таким синтаксисом. Мы создаем переменную, а потом эту переменную инициализируем результатом работы функции. Если мы запускаем любую функцию, которая есть в JavaScript коде, эта функция всегда что-то возвращает, и это возвращаемое значение мы можем присвоить переменной. Вот сейчас возвращаемое значение функции sum будет суммой двух аргументов, два и три. Поэтому в переменную рез запишется результат 5, результат на 22 строке мы отобразим. Давайте проверим. Вот отобразилось значение 5. Если мы сейчас возьмем и, например, поменяем 18 строчку, наберем ключевое слово return, функция у нас уже будет выполнять возврат значений. Теперь это значение будет undefined, потому что это значение по умолчанию. Если разработчик не указал, что функция возвращает, то функция всегда будет возвращать undefined. Давайте запустим. Видите, результат работы функции undefined. Поэтому если вы не написали return, или ключевое слово return просто не выполнилось в теле функции, это означает, что функция вернет значение undefined. И еще, то что вы должны понимать, ключевое слово return прекращает выполнение функции. Если после этого ключевого слова мы напишем сообщение, это сообщение у нас не выведется, потому что 17 строка, как только интерпретатор видит ключевое слово return и выполняет его, то вот на этом ключевом слове у нас и заканчивается работа функции. Мы из 17 строки перепрыгиваем в ту точку кода, где функция изначально запускалась, тот результат, который ключевым словом return был возвращен, мы записываем в переменную. Вот вернулась 5, а alert так и не отобразился.
Вторая часть урока будет посвящена областям видимости. Перед тем, как перейти к областям видимости мы повторим с вами что происходит с переменными, которые не создавали. Нам пригодится дальше для того, чтобы понимать следующий пример. На 13 строке мы создаем переменную «а». Помните, что если переменной мы не присваиваем значение, то значение этой переменной при чтении будет у нас undefined. Для остальных переменных мы задаем конкретное значение и соответственно переменные у нас инициализируются и получают какой-то определений тип данных. Переменная «b» со значением 777 она у нас будет number. На строке 15 переменная «c» использует значение переменной «b», соответственно это тоже будет number и тоже со значением 777. Переменная «d» будет типа null и содержать в себе единственное возможное для типа null значение null. Создав эти переменные мы отображаем их значения на экран и выводим все те значение, которые тут мы определили. Если же мы попытаемся получить доступ к переменной, которую не создавали, вот как на строке 24, то эта строчка кода становится ошибкой. На этой строчке интерпретатор прекращает интерпретировать все, что мы определили в сценарии и код находящийся ниже просто прекращает работать. Поэтому 24 строчка и все строчки кода, которые мы могли бы написать ниже, они не перестанут работать. Давайте проверим. Вот первая переменная undefined, потом обе переменные «b» и «c» со значением 777, переменная «d» – null. Последняя переменная – она у нас отсутствует. Если мы чтобы проверить, что действительно весь код перестает работать, если мы этот код поставим в начало, интерпретатор первое дело, что сделает – это выполнит эту строку, получит здесь ошибку и не сможет выполнять код идущий далее. Давайте запустим. Видите, в таком случае у нас вообще ничего не отображается. Поэтому следите за использованием переменных, не используйте переменные если вы их не определяли. То есть если мы хотя бы создали переменную, как только мы ее с помощью ключевого слова var определили, эта переменная остается, тип этой переменной undefined, значение этой переменной undefined. Дальше мы эту переменную можем спокойно использовать. А вот если вы пытаетесь читать переменные, которых нету, вот к чему это приводит. Приводит к ошибке.
Теперь давайте посмотрим, что такое область видимости. В следующем примере мы разберем с вами понятие глобальной и локальной области видимости. В языке JavaScript есть только две области видимости. Глобальная – это область видимости, где работают все наши сценарии. И локальная область видимости. Это область видимости, отдельной функции. Если вы работали в языке C# или С++ у вас есть глобальная область видимости и локальная область видимости, которая определяется функцией, которая определяется условием, циклом. В языке JavaScript таких вложенных областей видимости просто не существует. Либо у нас глобальная область видимости, либо область видимости функции. Если мы собираемся создать переменную глобальную, которая будет доступна абсолютно всем сценариям текущего приложения, текущего документа, нам нужно просто создать переменную в теге