Ivan Asmer 7 gadi atpakaļ
vecāks
revīzija
531d66bd09
2 mainītis faili ar 676 papildinājumiem un 0 dzēšanām
  1. 1 0
      A/04AssociativeArrays.md
  2. 675 0
      A/05Functions.md

+ 1 - 0
A/04AssociativeArrays.md

@@ -162,6 +162,7 @@ var obj = {
 
 ```javascript
 var obj2 = {...obj, surname: ''} //копируем obj и добавляем еще ключ
+var arr2 = [1,2,...[3,4,5]]      //добавление массива в массив
 ```
 
 

+ 675 - 0
A/05Functions.md

@@ -0,0 +1,675 @@
+
+# Функции, области видимости
+
+## Зачем?
+
+### Повторяющиеся действия.
+
+Как можно было заметить, компьютеры сильны именно в однотипных задачах, и делают простые задачи очень быстро. Связанные друг с другом однотипные задачи
+обычно
+повторяются в циклах (однотипные операции над массивами данных, статистические задачи, отрисовка повторяющихся данных на экране и так далее). Так же есть
+задачи *по требованию*, которые могут пригодится в любом месте кода. Например: `prompt`, `alert`, `Math.random` и прочие встроенные **функции**, которые
+являются *подпрограммами*,  содержащими в себе программный код, вызываемый для решения определенной задачи. Я думаю понятно, что данные возможности
+*не являются* возможностями аппаратуры, а воплощены на программном уровне. Это значит, что подпрограммы являются *естественными* в компьютерах.
+
+### DRY
+
+**Don't repeat yourself**. Один из основопологающих принципов разработки. Суть в том, что в процессе программирования вы должны минимизировать 
+повторяющиеся *части кода*, которые делают почти одинаковые задачи; так как копипаста в коде приводит к дублированию отладки, да и вообще некрасиво это
+:-)
+
+### KISS
+**Keep It Simple, Stupid**. Решайте задачи самым простым способом.
+> Отладка кода вдвое сложнее, чем его написание. Так что если вы пишете код настолько умно, насколько можете, то вы по определению недостаточно сообразительны, чтобы его отлаживать.
+> — *Brian W. Kernighan*.
+
+### DRY > KISS
+
+Зачастую эти принципы противоречат друг другу; уменьшение объема кода требует более мощных и сложнее отлаживаемых средств языка; однако в долгосрочной
+перспективе принцип **DRY** полезней, чем простота кода (**KISS**).
+
+### Пример
+
+```javascript
+var surname    = prompt("Введите фамилию","")
+if (surname === null || surname === ""){
+    surname    = "Иванов"
+}
+
+var name       = prompt("Введите имя","")      || "Иван"
+var fathername = prompt("Введите отчество","") || "Иванович"
+```
+
+Это наш пример, который спрашивает у пользователя ФИО ИЛИ берет эти параметры по умолчанию. Как видите, алгоритм ввода каждого из полей ФИО  однотипен, и его
+неплохо было бы выделить в **функцию**. Ко всему прочему, несмотря на эквивалентность алгоритма, `surname` вводится кодом, отличающимся от
+ввода `name` и `fathername`, что усложняет модификацию и отладку кода.
+
+### Задание
+
+Порассуждаем о функциях, какие свойства должны быть у них, что бы они обеспечивали прозрачную работу в комбинации с другим кодом и не имели
+непредсказуемых побочных эффектов для кода, который их использует.
+
+# Ниже спойлер, имейте совесть :-D. Не омрачайте задание подглядыванием ответов.
+![СПОЙЛЕР](http://www.bugaga.ru/uploads/posts/2013-07/1372949635_spoyler-10.jpg)
+![СПОЙЛЕР](http://www.bugaga.ru/uploads/posts/2013-07/1372949635_spoyler-10.jpg)
+![СПОЙЛЕР](http://www.bugaga.ru/uploads/posts/2013-07/1372949635_spoyler-10.jpg)
+![СПОЙЛЕР](http://www.bugaga.ru/uploads/posts/2013-07/1372949635_spoyler-10.jpg)
+
+## Функции
+
+**Функция** - подпрограмма, которая принимает определенные параметры при вызове, выполняет определенный код, и возвращает выполнение кода в место вызова,
+*опционально* (не обязательно) вернув результат работы в место вызова.
+
+### Свойства функций,
+...которые сделали её такой полезной для написания программ:
+
+#### Вызов. 
+Функция может быть вызвана любое количество раз из разных несвязанных между собой мест кода, код функции выполнится, после чего выполнение кода
+   продолжится с места вызова:
+
+```javascript
+var callCounter = 0;
+function ourFunction()
+{
+    alert("Вызов № " + callCounter);
+    callCounter ++;
+}
+console.log(callCounter);
+ourFunction()
+console.log(callCounter);
+//тут еще может быть много кода, но мы можем опять воспользоваться функцией когда захотим:
+ourFunction()
+console.log(callCounter);
+```
+Вызов происходит при наличии скобок после имени функции. Если скобок нет - вызов не происходит и это имеет совершенно другой смысл.
+Для входа и выхода из функции используются `F11` и `Shift-F11` в **Developer Tools** при **пошаговой отладке**
+
+#### Область видимости.
+Так как функция не может "знать", из какого контекста она вызывается, то нет возможности знать заранее, совпадают ли имена
+переменных в функции и вне её. Таким образом вероятны *побочные эффекты* - непредсказуемые изменения переменных во внешнем коде, которые могут
+вызвать неправильную работу кода в целом. Побочные эффекты возникают при совпадении внутренних и внешних переменных:
+
+```javascript
+var surname = "Петров";
+function readSurname()
+{
+    surname = prompt("Введите фамилию","") //тут мы портим внешнюю переменную surname, и это нехорошо
+    if (surname === null || surname === ""){
+        surname = "Иванов"
+    }
+}
+
+console.log(surname);
+readSurname();
+console.log(surname);
+```
+
+Для решения этой проблемы используется концепция *области видимости* - **правильно** объявленная переменная
+в функции (через `var`) существует только в функции и создается каждый раз при вызове функции; внешние же переменные с таким же именем остаются
+нетронутыми. 
+
+#### **ES6** `let`
+
+`let` из **ES6** создает область видимости без вызова функции в блоке кода, в котором определена переменная через `let`.
+
+```javascript
+var surname = "Петров";
+function readSurname()
+{
+    var surname = prompt("Введите фамилию","") // тут мы ничего не портим, эта переменная НЕ ЯВЛЯЕТСЯ внешней переменной surname
+    if (surname === null || surname === ""){
+        surname = "Иванов"
+    }
+}
+console.log(surname);
+readSurname();
+console.log(surname);
+```
+
+#### **Параметры**.
+Функция должна уметь получить те или иные данные для своего выполнения. Например встроенные функции `confirm`, `prompt`, `alert`.
+
+**Задание**: Каковы параметры и какой у них смысл в вышеуказанных встроенных функциях?
+
+```javascript
+var name = "Yohan"
+function greet(name){ 
+    alert("Hello, " + name);
+}
+
+greet(name)
+greet("John")
+greet("Paul")
+console.log(name)
+```
+
+#### **Возвращаемое значение**.
+Обратите внимание на то, что **функции** можно использовать как переменные в выражениях, однако не всегда это имеет смысл. 
+Более того, **результату** функции нельзя присвоить значение, однако можно *прочесть* результат, вызвав функцию. 
+
+**Задание**: какие из функций `prompt`, `confirm` и `alert` возвращают значения, а какие - нет?
+
+```javascript
+function random5(){
+    return Math.random()*5;
+}
+
+alert(random5());
+var someRandomValueFromZeroToFive = random5();
+```
+
+## Определение и выполнение функций
+
+Обратите внимание, что первый `alert` происходит ДО включения пошаговой отладки. Это говорит о том, что *определение функции* **НЕ** вызывает её. 
+Код функции работает только после вызова, который происходит по `d()`. Для вызова надо указать в коде имя функции и скобки после имени (с параметрами
+или без оных)
+```javascript
+function d()
+{
+    debugger;
+}
+alert("before d");
+d()
+alert("after d");
+```
+
+Определение начинается с ключевого слова `function`, после которого идет имя функции и параметры в скобках через запятую. Далее идет блок кода функции
+в фигурных скобках. В отличие от `if`, `else` и циклов, фигурные скобки **обязательны**.
+
+При отладке и/или чтении чужого кода ищите вызовы функций. *Иногда* вызовы скрыты.
+
+### Именование функций
+
+Как и переменным, функциям нужно давать осмысленные названия. Только учтите, что переменные - *существительные* кода, а функции - *глаголы* кода.
+
+### Выполнение функций.
+
+Когда в коде упоминается имя функции со скобками и, возможно, параметрами происходят следующие действия:
+- вычисляются выражения в скобках. В функцию попадают уже *значения* выражений.
+- создается новая область видимости, в которую попадают параметры и их значения. Вам не нужно определять переменные для параметров.
+- начинается выполнение кода в фигурных скобках определения функции. Все переменные, определенные через `var` попадают в локальную область видимости функции, не перекрывающую внешнюю область видимости.
+- Код выполняется до выполнения `return` или окончания кода функции (закрывающей фигурной скобки). `return` прерывает выполнение функции, более того, 
+  с помощью `return` происходит возврат значения функции, которое подставляется на место вызова функции. Таким образом функция ведет себя как 
+  *переменная* для чтения. Если функция ничего не возвращает, то, на самом деле, она возвращает `undefined`
+
+```javascript
+function sqr(a){
+    alert("Вы передали:" + a);
+    return a*a;
+    alert("Этот код не выполнится");
+}  
+
+var sqr1 = sqr(5)
+var otherVar = 2;
+alert("Сумма квадратов: " + (sqr1 + sqr(otherVar + otherVar)));
+```
+
+## Параметры функции и возвращаемое значение
+
+### Параметры (аргументы)
+
+Параметры функции перечисляются в скобках после имени через запятую. Параметры - это переменные области видимости функции, в которые попадают
+вычисленные значения, передаваемые при **вызове**. Таким образом функции получают данные из внешнего кода.
+
+В **Javascript** количество параметров при определении и при вызове может отличаться. Это не вызывает ошибок. В таком случае непереданные параметры равны 
+`undefined`:
+```javascript
+debugger;
+function add(a,b)
+{
+    a = a || 0;
+    b = b || 0;
+    return a + b;
+}
+
+alert(add())
+alert(add(1));
+alert(add(2,3));
+```
+
+Если же параметров больше, чем указано в определении функции, то ошибки тоже не происходит. Для доступа к полям существует **псевдомассив**
+`arguments`, который всегда содержит актуальный набор параметров, переданных при вызове. 
+```javascript
+debugger;
+function add(a,b)
+{
+    console.log(arguments)
+    a = a || 0;
+    b = b || 0;
+    return a + b;
+}
+
+alert(add(4,5,6))
+alert(add(4,5,6,7));
+
+prompt("Введите число", "0");
+prompt("Введите число");
+```
+
+#### **ES6** rest/spread в аргументах функции
+
+Кроме псевдомассива `arguments`, который присутствует в языке давно, в синтаксисе **ES6** есть еще `rest/spread` для аргументов функции:
+
+```javascript
+add(5,6)
+add(...[1,2]) //передача параметров из массива 
+
+function manyAdd(...params) // параметры собираются в массив params
+{
+    return params.reduce((a,b) => a + b)
+}
+
+manyAdd(4,5,6,7)
+manyAdd(...[4,5,6,7])
+```
+
+
+**Задание**
+
+Используя перебор массива `arguments` циклом `for`, сделайте функцию, которая складывает любое количество параметров
+
+### Возвращаемое значение
+
+Для возврата значения используется `return`. У него три основных свойства:
+- Собственно возврат значения во внешний код. Выражение после `return` *вычисляется в контексте функции*:
+
+```javascript
+debugger;
+function add(a,b)
+{
+    return a + b; 
+}
+alert(add(3,4))
+```
+
+после чего *значение* попадает в место, где функция была вызвана (в `alert`)
+- Прекращение выполнения функции
+- `return` без параметра возвращает *ничего*, т. е. `undefined`:
+
+```javascript
+debugger;
+function bigAndWeirdFunction()
+{
+    var somethingBad = Math.random() > 0.5;
+    if (somethingBad){
+        alert("Something bad happens");
+        return;
+    }
+    alert("All OK!");
+}
+bigAndWeirdFunction();
+bigAndWeirdFunction();
+bigAndWeirdFunction();
+```
+
+### `console.log` и `return`
+
+При отладке вы видите в одной консоли  *вычисленное значение выражения* (например `2 + 2` или `prompt("Введите число")`) и вывод `console.log`. 
+`console.log` *просто выводит текст* в консоль, как `document.write` - в окно браузера, далее вы с этим ничего не можете сделать (почти). 
+**Выражение** же может быть вставлено в код и являться частью другого выражения:
+
+```javascript
+2 + 2
+var a = 2 + 2
+prompt("Введите число");
+var num = prompt("Введите число");
+
+var b;
+    b = console.log(a); //неработает, метод log объекта console возвращает undefined, т. е. ничего
+    b = a; //работает
+
+function myLowerCase(str)
+{
+    console.log(str.toLowerCase()); //это просто пишет текст в консоли.
+}
+
+function rightUpperCase(str)
+{
+    return str.toUpperCase(); //это работает правильно
+}
+
+var lowerCase = myLowerCase("AbCdEf") //не работает.
+var upperCase = rightUpperCase("AbCdEf") //работает
+```
+
+Что бы отличить результат выражения от вывода console.log, отметьте что возле значения выражения есть знак `<`.
+
+## Область видимости
+
+Как было указано выше, переменные, объявленные с `var` внутри функции, являются незаметными для окружающего кода и перекрывают совпадающие переменные
+внутри функции, оставляя невредимыми внешние переменные:
+
+```javascript
+var a = 5;
+
+alert("global a: " + a);
+function someFunctionWithA(){
+    var a = "string";
+    alert("function scope a: " + a);
+}
+
+alert("global a after function declaration" + a);
+someFunctionWithA()
+alert("global a after function execution" + a);
+```
+
+Область видимости создается **каждый раз** при **вызове** функции:
+
+```javascript
+
+debugger;
+function add(a,b)
+{
+    var result = a + b;
+    return result;
+}
+
+add(1,2)
+add(5,6)
+```
+
+Как видите, переменные `a`,`b` и `result` каждый раз имеют разные значения. При вызове область видимости создается, по выходу из функции - удаляется
+(*не всегда*).
+
+### Глобальная область видимости
+
+Если переменная создается **без** `var` в *любом* месте кода, в том числе в функции, она является глобальной, т. е. видимой везде.
+В ES5 это значит что любая переменная без `var` попадает в объект `window`.
+В ES6 это вызывает ошибку.
+
+```javascript
+debugger;
+function add(a,b)
+{
+    result = a + b;
+    return result;
+}
+
+result = add(1,2)
+alert(result);
+add(5,6)
+alert(result);
+```
+
+Как видно в примере выше, мы не можем расчитывать на целостность переменной `result`, пользуясь функцией `add`. Использование глобальных переменных
+в большинстве случаев неоправдано; они нужны в-основном только для каких-то общих данных для чтения. Например `Math.PI` является глобальной переменной,
+доступной только на чтение; то есть *константой*. Ваши же переменные будут доступны и на запись, будьте аккуратны используя их.
+
+**Общее правило**: всегда ставьте `var`.
+
+
+### Вложенные функции и их области видимости
+
+```javascript 
+var a = "0";
+var b = "0";
+var c = "0";
+
+function level1(){
+    var b = "1";
+    var c = "1";
+
+    function level2(){
+        var c = "2";
+        console.log("Level 2 scope: a: " + a + " b: " + b + " c: " + c);
+    }
+    level2();
+    console.log("Level 1 scope: a: " + a + " b: " + b + " c: " + c);
+}
+
+level1();
+console.log("Level 0 scope: a: " + a + " b: " + b + " c: " + c);
+```
+Проанализируйте вывод кода выше. Самая вложенная функция `level2` видит переменные своей области видимости (`c`), потом ищет значение на уровень
+выше (для переменной `b`), и на уровень еще выше (для `a`). Промежуточная функция `level1` *ничего* не знает о переменных в `level2`, но видит свою
+область видимости и глобальную. Глобальная же имеет свои переменные `a`, `b`, `c` в первозданном виде.
+
+```javascript 
+var a = "0";
+var b = "0";
+var c = "0";
+
+function level1(){
+    var b = "1";
+    var c = "1";
+    var d = "1";
+
+    function level2(){
+        var c = "2";
+        var e = "2";
+        console.log("Level 2 scope: a: " + a + " b: " + b + " c: " + c + " d: " + d + " e: " + e); 
+        d = "2";
+    }
+    console.log("Level 1 before level2, scope: a: " + a + " b: " + b + " c: " + c + " d: " + d + " e: " + e);
+    level2();
+    console.log("Level 1 after  level2, scope: a: " + a + " b: " + b + " c: " + c + " d: " + d + " e: " + e);
+}
+
+level1();
+console.log("Level 0 scope: a: " + a + " b: " + b + " c: " + c + " d: " + d + " e: " + e);
+```
+
+Данный пример иллюстрирует отсутствие переменных `e` в глобальной области видимости и `level1`, переменной `d` - в глобальной области видимости. Переменная
+`d` попадает из `level1` в `level2`.
+
+## Функции высшего порядка.
+
+### Функция как тип данных.
+
+Функции в **JS** являются *типом данных*, наряду с числами и строками. Определение функции является выражением и вычисляется как значение типа данных
+`function`:
+
+```javascript
+function a(){
+}
+alert(typeof a);
+```
+
+Набор операций с функциями невелик, в отличие от строк их нельзя конкатенировать, нельзя складывать и умножать как числа; однако их можно присваивать
+переменным и вызывать. **JS** позволяет создавать функции без названия:
+
+```javascript
+a();
+function a(){
+    console.log('declared func');
+}
+
+someFuncVariable()
+var someFuncVariable = function (){
+    console.log('anon func');
+}
+
+someFuncVariable()
+
+var b = a;
+a = null;
+a()
+a = b
+a()
+```
+
+
+### Знакомство: ООП в функциональном стиле. .
+
+Как видите, функция - такой же тип данных, как и остальные, однако этот тип имеет другой набор допустимых операций; в основном функции создают, передают и запускают.
+Так как ассоциативные массивы в **JS** могут хранить любой тип данных, то функции тоже могут быть элементами объектов. Таким образом реализуется **ООП** в **JS**:
+
+```javascript
+var rectangle = {
+    x: 0,
+    y: 0,
+    w: 100,
+    h: 100,
+    color: "black",
+
+    draw: function(/* this */){
+        console.log("I'm drawing a rectangle with coordinates " + this.x + "x" + this.y + " and dimensions " + this.w + 'x' + this.h + " in " + this.color + " color");
+    },
+
+    setColor: function(/* this, */ color){
+        this.color = color;
+        this.draw();
+    }
+}
+
+rectangle.draw();
+```
+
+`this` - это скрытый параметр функции (*контекст*), который позволяет функциям-полям объектов получить доступ к другим полям объекта (`x`, `y` и другие в примере выше)
+
+
+### **ES6** стрелочные функции
+
+В синтаксисе **ES6** существует короткая удобная запись для анонимных функций:
+Синтаксически это `=>`, параметры до этой пары символов, выражение-результат функции - после:
+
+```javascript
+var sqr = x => x*x //один параметр, скобки не нужны
+alert(sqr(2))
+
+var mul = (x,y) => x*y //два параметра - нужны скобки
+alert(mul(2,5))
+
+var objectCreator = (x,y) => ({x, y}) //создает объект {x: x, y: y}. Если забыть скобки - то JS воспримет {x,y} как блок кода, и без return вернет undefined
+console.log(objectCreator(4,5))
+
+var longFunc = (x,y) => { //почти обычная функция
+    let result = prompt(x,y)
+    return result;
+}
+
+longFunc('check', 'text')
+
+### Функции высшего порядка
+
+**Функциями высшего порядка** называют функции, которые оперируют другими функциями - принимают их в качестве параметров или возвращают как результат 
+выполнения. Такой подход позволяет произвести *инъекцию своего кода*. Например, все реализации алгоритма сортировки сравнивают разные сортируемые элементы,
+при этом для работы алгоритма *вовсе не обязательно* знать структуру сортируемых данных; достаточно просто знать, какой элемент из двух *больше* или *меньше*.
+
+Функция, передаваемая в качестве параметра другой функции для последующего вызова называется `callback`.
+
+```javascript
+var production = [1,2,3,4].reduce((a,b) => a * b)
+var numbers    = [prompt(), prompt(), prompt()].map(function(a){
+    return +a;
+})
+```
+
+```javascript
+var arrayOfNumbers = [4,18,10,2,-1,100, 0, 0.5];
+arrayOfNumbers.sort(); //сортирует, используя обычное строковое сравнение `<` и `>`
+
+function numberSort(a, b){
+    var result = a > b ? 1 : -1;
+    console.log("Нас вызвали для сравнения " + a + " и " + b + ". Результат будет " + result);
+    return result;
+}
+arrayOfNumbers.sort(numberSort); //сортировка по числовому значению
+```
+
+Первый `sort` выше сортирует, используя знаки `<` для элементов массива, интерпретируя элементы как строки;
+
+Второй `sort` принимает в качестве параметра функцию, которая вызывается многократно внутри `sort` для некой пары сортируемых элементов. Пара выбирается согласно логике
+алгоритма сортировки; выбор же, кто из этих двух элементов больше, а кто - меньше, возлагается на переданную функцию `numberSort`, которая должна вернуть
+1 если `а` считается больше `b` и -1 в обратном случае. В случае равенства `a` и `b` - возвращается 0, однако это можно не использовать
+
+Таким же образом мы можем отсортировать по тому или иному критерию массив объектов (ассоциативных массивов), например:
+
+```javascript
+var persons = [
+    {name: "Иван", age: 17},
+    {name: "Мария", age: 35},
+    {name: "Алексей", age: 73},
+    {name: "Яков", age: 12},
+]
+persons.sort(function(a,b){ //сортируем по возрасту
+    if (a.age > b.age){
+        return 1;
+    }
+    return -1;
+});
+
+persons.sort(function(a,b){ //сортируем по имени
+    if (a.name > b.name){
+        return 1;
+    }
+    return -1;
+});
+```
+
+Рассмотрим пример:
+
+```javascript
+function intPrompt(message, defaultValue)
+{
+    do {
+        var value = prompt(message, defaultValue)
+    } while(value !== null && isNaN(+value) || !Number.isInteger(+value))
+    return value
+}
+
+function gamePrompt(message, defaultValue)
+{
+    do {
+        var value = prompt(message, defaultValue)
+    } while(value !== null && !(value == 'камень' || value == 'ножницы' || value == 'бумага'))
+    return value
+}
+
+```
+Далее идет **общее** решение ввода с валидацией:
+
+```javascript
+function validatedPrompt(message, defaultValue, validator)
+{
+    do {
+        var value = prompt(message, defaultValue);
+    } while( value !== null && !validator(value));
+    return value;
+}
+debugger;
+alert(validatedPrompt("number", "", function(value) {
+            return !isNaN(+value) && Number.isInteger(+value) 
+}))
+
+alert(validatedPrompt("камень-нжнцы-бмг", "", function(value) {
+            return ["камень", "ножницы", "бумага"].indexOf(value.toLowerCase()) > -1;
+}))
+```
+
+В этом примере код валидации выделен в функцию обратного вызова, а общее решение циклического ввода находится в функции `validatedPrompt`
+
+## Для чего используются функции.
+
+- Для избавления повторяющихся кусков кода. **DRY**
+- Для структуризации и задания имени какой-либо последовательности операций. Например зачастую в начале работы кода запускают однократно функцию
+ `init` (имя приведено для примера), которая выполняется *один* раз, т. е. не уменьшает объем кода. Однако, таким образом, все действия, которые 
+  относятся к подготовке программного окружения, заносятся в отдельный блок кода, что более наглядно
+- Функции обратного вызова используются для внедрения кода, как в случае с `sort` и `validatedPrompt`
+- Функции обратного вызова используются для того, что бы отказаться от опроса (poll) и перейти к событийной архитектуре (push), т. е. вместо
+  постоянной проверки произошло то или иное событие или нет - происходит вызов callback когда это событие произошло.
+
+```javascript
+console.log("Начал");
+setTimeout(function(){
+    console.log("Отложил на 5 сек");
+}, 5000);
+console.log("Закончил");
+```
+  В этом примере, вместо того, что бы засекать время и постоянно в цикле проверять, прошел ли нужный промежуток времени (5 секунд), используется
+  встроенная функция setTimeout, которая запускает ваш код через определенное время. Код предоставляется в форме функции, время вторым параметром
+  в миллисекундах.
+
+- Функции используются для создания обособленной области видимости, что бы не нарушать окружающее пространство имен:
+
+```javascript
+(function(){
+    var a = 5;
+    var b = "100500";
+})()
+```
+в данном примере создается функция и тут же вызывается. Функция не сохраняется ни в какой из переменных, а значит вы не сможете её вызвать более
+чем один раз. Единственная цель такой функции (**Self-Invoked Function**) - создать свою собственную область видимости, в которой можно оперировать
+любыми именами переменных не опасаясь побочных эффектов и влияния на переменные окружающего кода. Просто блок кода со своими именами. В **ES6** для
+этих целей есть `let`, однако вы не раз увидите подобный код на **ES5**.
+