Область видимости
Важно
Область видимости — важная концепция, определяющая доступность переменных. Данная концепция лежит в основе замыканий, разделяя переменные на глобальные и локальные.
Область видимости создается каждый раз при вызове функции:
1function add(a,b)2{3 var result = a + b;4 return result;5}67add(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}67result = add(1,2)8console.log(result);9add(5,6)10console.log(result);
Как видно в примере выше, мы не можем расчитывать на целостность переменной result
, пользуясь функцией add
. Использование глобальных переменных
в большинстве случаев неоправдано; они нужны в основном только для каких-то общих данных для чтения.
Общее правило
всегда ставьте var
.
Цепочки областей видимости
Окружение имеет доступ к окружению своего родителя, его родительское окружение имеет доступ к своему родительскому окружению и так далее. Этот набор идентификаторов, к которому каждое окружение имеет доступ, называется область видимости — scope. Мы можем вложить их в иерархические цепочки окружения, известные как цепочки областей видимости.
1var x = 10;23function foo() {4 var y = 20; // свободная переменная5 function bar() {6 var z = 15; // свободная переменная7 return x + y + z;8 }9 return bar;10}
Вложенные функции и их области видимости
1var a = "0";2var b = "0";3var c = "0";45function level1(){6 var b = "1";7 var c = "1";89 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}1617level1();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";45function level1(){6 var b = "1";7 var c = "1";8 var d = "1";910 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}2021level1();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 = ["_", "_", "_", "_"];34function findLetter(letter){56 /// your code here7}89findLetter('H');10findLetter('O');11findLetter('W');12findLetter('L');13findLetter('M')14findLetter('E')1516console.log('wordLetters',guessedLetters) // ["H", "O", "M", "E"]
Задание :three:
Разработать алгоритм:
Дано множество камней разного веса. Разбросать их на две кучи максимально одинакового веса.
В нашем случае куча это массив, а вес камня это число, чем выше число тем больше вес у камня.
1function calculate(arr){2// your code3return {4 a:[],5 b:[]6}7}89calculate([1,1,2,3]) // { a:[1,2], b:[1,3}