HTML / CSSJavaScriptNode jsПаттерны проектированияПрактические

Область видимости

❗️Важно

Область видимости — важная концепция, определяющая доступность переменных. Данная концепция лежит в основе замыканий, разделяя переменные на глобальные и локальные.

Область видимости создается каждый раз при вызове функции:

1function add(a,b)
2{
3 var result = a + b;
4 return result;
5}
6
7add(1,2)
8add(5,6)

Как видите, переменные a,b и result каждый раз имеют разные значения. При вызове область видимости создается, по выходу из функции - удаляется (не всегда).

Глобальная область видимости

Если переменная создается без var в любом месте кода, в том числе в функции, она является глобальной, т. е. видимой везде. В ES5 это значит что любая переменная без var попадает в объект window. В ES6 это вызывает ошибку.

1function add(a,b)
2{
3 result = a + b;
4 return result;
5}
6
7result = add(1,2)
8console.log(result);
9add(5,6)
10console.log(result);

Как видно в примере выше, мы не можем расчитывать на целостность переменной result, пользуясь функцией add. Использование глобальных переменных в большинстве случаев неоправдано; они нужны в основном только для каких-то общих данных для чтения.

🔥Общее правило

всегда ставьте var.

Цепочки областей видимости

Окружение имеет доступ к окружению своего родителя, его родительское окружение имеет доступ к своему родительскому окружению и так далее. Этот набор идентификаторов, к которому каждое окружение имеет доступ, называется область видимости — scope. Мы можем вложить их в иерархические цепочки окружения, известные как цепочки областей видимости.

1var x = 10;
2
3function foo() {
4 var y = 20; // свободная переменная
5 function bar() {
6 var z = 15; // свободная переменная
7 return x + y + z;
8 }
9 return bar;
10}
chain

Вложенные функции и их области видимости

1var a = "0";
2var b = "0";
3var c = "0";
4
5function level1(){
6 var b = "1";
7 var c = "1";
8
9 function level2(){
10 var c = "2";
11 console.log("Level 2 scope: a: " + a + " b: " + b + " c: " + c);
12 }
13 level2();
14 console.log("Level 1 scope: a: " + a + " b: " + b + " c: " + c);
15}
16
17level1();
18console.log("Level 0 scope: a: " + a + " b: " + b + " c: " + c);

Проанализируйте вывод кода выше. Самая вложенная функция level2 видит переменные своей области видимости (c), потом ищет значение на уровень выше (для переменной b), и на уровень еще выше (для a). Промежуточная функция level1 ничего не знает о переменных в level2, но видит свою область видимости и глобальную. Глобальная имеет свои переменные a, b, c в первозданном виде.

1var a = "0";
2var b = "0";
3var c = "0";
4
5function level1(){
6 var b = "1";
7 var c = "1";
8 var d = "1";
9
10 function level2(){
11 var c = "2";
12 var e = "2";
13 console.log("Level 2 scope: a: " + a + " b: " + b + " c: " + c + " d: " + d + " e: " + e);
14 d = "2";
15 }
16 console.log("Level 1 before level2, scope: a: " + a + " b: " + b + " c: " + c + " d: " + d + " e: " + e);
17 level2();
18 console.log("Level 1 after level2, scope: a: " + a + " b: " + b + " c: " + c + " d: " + d + " e: " + e);
19}
20
21level1();
22console.log("Level 0 scope: a: " + a + " b: " + b + " c: " + c + " d: " + d + " e: " + e);

Данный пример иллюстрирует отсутствие переменных e в глобальной области видимости и level1, переменной d - в глобальной области видимости. Переменная d попадает из level1 в level2.

Практика 👩‍💻👨‍💻

Задание :one:

Напишите функцию cube, которая возвращает число в третьей степени:

1function cube(){
2}

Задание :two:

Пользователь имеет бесконечное количество попыток угадать слово.

Создайте два глобальных массива: один для хранения букв слова (например, 'F', 'O', 'X'), а другой для хранения текущих угаданных букв (например, он будет начинаться с _, _, _ и заканчиваются буквами 'F', 'O', 'X').

1var wordLetters = ["H", "O", "M", "E"];
2var guessedLetters = ["_", "_", "_", "_"];

Напишите функцию под названием guessLetter, которая будет:

  • Принимает один аргумент, угаданного слово.
  • Перебрать буквы загаданного слова и посмотреть, есть ли там угаданная буква.
  • Если угадываемая буква соответствует букве слова, измените массив guessedLetters, чтобы отразить это.
  • При следующем вызове функции массив guessedLetters должен содержать угаданную букву ["H", "_", "_", "_"] и поздравить пользователя, если он нашел букву.
  • Следует также выяснить, есть ли еще буквы, которые нужно угадать, если нет, он должен поздравить пользователя с победой в игре.
1var wordLetters = ["H", "O", "M", "E"];
2var guessedLetters = ["_", "_", "_", "_"];
3
4function findLetter(letter){
5
6 /// your code here
7}
8
9findLetter('H');
10findLetter('O');
11findLetter('W');
12findLetter('L');
13findLetter('M')
14findLetter('E')
15
16console.log('wordLetters',guessedLetters) // ["H", "O", "M", "E"]

Задание :three:

Разработать алгоритм:

Дано множество камней разного веса. Разбросать их на две кучи максимально одинакового веса.

В нашем случае куча это массив, а вес камня это число, чем выше число тем больше вес у камня.

1function calculate(arr){
2// your code
3return {
4 a:[],
5 b:[]
6}
7}
8
9calculate([1,1,2,3]) // { a:[1,2], b:[1,3}
Hello