|
@@ -8,7 +8,7 @@
|
|
|
повторяются в циклах (однотипные операции над массивами данных, статистические задачи, отрисовка повторяющихся данных на экране и так далее). Так же есть
|
|
|
задачи *по требованию*, которые могут пригодится в любом месте кода. Например: `prompt`, `alert`, `Math.random` и прочие встроенные **функции**, которые
|
|
|
являются *подпрограммами*, содержащими в себе программный код, вызываемый для решения определенной задачи. Я думаю понятно, что данные возможности
|
|
|
-*не являются* возможностями аппаратуры, а воплощены на программном уровне.
|
|
|
+*не являются* возможностями аппаратуры, а воплощены на программном уровне. Это значит, что подпрограммы являются *естественными* в компьютерах.
|
|
|
|
|
|
### DRY
|
|
|
|
|
@@ -38,7 +38,7 @@ var name = prompt("Введите имя","") || "Иван"
|
|
|
var fathername = prompt("Введите отчество","") || "Иванович"
|
|
|
```
|
|
|
|
|
|
-Это наш пример, который спрашивает у пользователя ФИО ИЛИ берет эти параметры по умолчанию. Как видите, алгоритм ввода ФИО однотипен, и его
|
|
|
+Это наш пример, который спрашивает у пользователя ФИО ИЛИ берет эти параметры по умолчанию. Как видите, алгоритм ввода каждого из полей ФИО однотипен, и его
|
|
|
неплохо было бы выделить в **функцию**. Ко всему прочему, несмотря на эквивалентность алгоритма, `surname` вводится кодом, отличающимся от
|
|
|
ввода `name` и `fathername`, что усложняет модификацию и отладку кода.
|
|
|
|
|
@@ -60,30 +60,31 @@ var fathername = prompt("Введите отчество","") || "Иванови
|
|
|
|
|
|
Свойства **функции**, которые сделали её такой полезной для написания программ:
|
|
|
|
|
|
-- **Вызов**. Функция может быть вызвана любое количество раз, код функции выполнится в другом месте, после выполнения функции выполнение кода
|
|
|
+- **Вызов**. Функция может быть вызвана любое количество раз из разных несвязанных между собой мест кода, код функции выполнится, после чего выполнение кода
|
|
|
продолжится с места вызова:
|
|
|
|
|
|
```javascript
|
|
|
-function d()
|
|
|
+var callCounter = 0;
|
|
|
+function ourFunction()
|
|
|
{
|
|
|
- debugger;
|
|
|
+ alert("Вызов № " + callCounter);
|
|
|
+ callCounter ++;
|
|
|
}
|
|
|
-alert("before d");
|
|
|
-d()
|
|
|
-alert("after d");
|
|
|
-d()
|
|
|
+ourFunction()
|
|
|
+//тут еще может быть много кода, но мы можем опять воспользоваться функцией когда захотим:
|
|
|
+ourFunction()
|
|
|
```
|
|
|
Для входа и выхода из функции используются `F11` и `Shift-F11` в **Developer Tools** при **пошаговой отладке**
|
|
|
|
|
|
- **Область видимости**. Так как функция не может "знать", из какого контекста она вызывается, то нет возможности знать заранее, совпадают ли имена
|
|
|
переменных в функции и вне её. Таким образом вероятны *побочные эффекты* - непредсказуемые изменения переменных во внешнем коде, которые могут
|
|
|
- вызвать неправильную работу кода в целом;
|
|
|
+ вызвать неправильную работу кода в целом. Побочные эффекты возникают при совпадении внутренних и внешних переменных:
|
|
|
|
|
|
```javascript
|
|
|
var surname = "Петров";
|
|
|
function readSurname()
|
|
|
{
|
|
|
- surname = prompt("Введите фамилию","")
|
|
|
+ surname = prompt("Введите фамилию","") //тут мы портим внешнюю переменную surname, и это нехорошо
|
|
|
if (surname === null || surname === ""){
|
|
|
surname = "Иванов"
|
|
|
}
|
|
@@ -103,7 +104,7 @@ alert(surname);
|
|
|
var surname = "Петров";
|
|
|
function readSurname()
|
|
|
{
|
|
|
- var surname = prompt("Введите фамилию","") // ТУТ
|
|
|
+ var surname = prompt("Введите фамилию","") // тут мы ничего не портим, эта переменная НЕ ЯВЛЯЕТСЯ внешней переменной surname
|
|
|
if (surname === null || surname === ""){
|
|
|
surname = "Иванов"
|
|
|
}
|
|
@@ -117,35 +118,27 @@ alert(surname);
|
|
|
**Задание**: Каковы параметры и какой у них смысл в вышеуказанных встроенных функциях?
|
|
|
|
|
|
```javascript
|
|
|
-var surname = "Петров";
|
|
|
-function readWithDefault(promptText, promptDefault, somethingDefault)
|
|
|
-{
|
|
|
- var something = prompt(promptText,promptDefault)
|
|
|
- if (something === null || something === ""){
|
|
|
- something = somethingDefault;
|
|
|
- }
|
|
|
- alert("something: " + something);
|
|
|
+var name = "Yohan"
|
|
|
+function greet(name){
|
|
|
+ alert("Hello, " + name);
|
|
|
}
|
|
|
-alert(surname);
|
|
|
-readWithDefault("Введите фамилию","","Иванов");
|
|
|
+
|
|
|
+greet(name)
|
|
|
+greet("John")
|
|
|
+greet("Paul")
|
|
|
```
|
|
|
|
|
|
- **Возвращаемое значение**. Обратите внимание на то, что **функции** можно использовать как переменные в выражениях, однако не всегда это имеет смысл.
|
|
|
- Более того, **результату** функции нельзя присвоить значение, однако можно *прочесть* результат, вызвав функцию.
|
|
|
+ Более того, **результату** функции нельзя присвоить значение, однако можно *прочесть* результат, вызвав функцию.
|
|
|
+ **Задание**: какие из функций `prompt`, `confirm` и `alert` возвращают значения, а какие - нет?
|
|
|
|
|
|
```javascript
|
|
|
-var surname = "Петров";
|
|
|
-function readWithDefault(promptText, promptDefault, somethingDefault)
|
|
|
-{
|
|
|
- var something = prompt(promptText,promptDefault)
|
|
|
- if (something === null || something === ""){
|
|
|
- something = somethingDefault;
|
|
|
- }
|
|
|
- return something;
|
|
|
+function random5(){
|
|
|
+ return Math.random()*5;
|
|
|
}
|
|
|
-alert(surname);
|
|
|
-var name = readWithDefault("Введите имя","","Иван");
|
|
|
-alert(name);
|
|
|
+
|
|
|
+alert(random5());
|
|
|
+var someRandomValueFromZeroToFive = random5();
|
|
|
```
|
|
|
|
|
|
## Определение и выполнение функций
|