Виды контекста в JavaScript +2
JavaScript, Программирование, Блог компании OTUS. Онлайн-образование
Рекомендация: подборка платных и бесплатных курсов дизайна интерьера - https://katalog-kursov.ru/
И снова здраствуйте! Мы уже писали о том, что в конце сентября в OTUS стартует новый поток курса «Fullstack разработчик JavaScript». В преддверии начала занятий продолжаем делиться с вами авторскими статьями, подготовленными специально для студентов курса. Сегодня разберем виды контекста в JavaScript. Поехали.
Автор статьи: Павел Якупов
Цель данной статьи состоит в том, чтобы читатель понял основные концепции областей видимости, которые используются в JavaScript.
Область видимости одна из самых важных вещей в JavaScript (и имеет место быть в большинстве современных языков программирования). Область видимости(Scope) связана с длинной жизни переменной или функции, доступом, видимостью переменных, и некоторыми другими вещами.
Зачем вообще нам нужна это область видимости?
Область видимости в языках программирования выполняет следующие функции:
Безопасность(инкапсуляция) — переменные и функции доступны только когда они понадобятся.
Устраняет проблему конфликта имен переменных. Наличие областей видимости позволяет не «сваливать» в одну кучу все переменные, симулируя пространства имен(namespace).
Реиспользование кода — написанный код можно потом использовать, избегая «посторонних» эффектов.
Типы областей видимости
На самом простом уровне, в JavaScript существует две области видимости — локальная и глобальная.
В этой статье мы также затронем такую область видимости, как лексическая и блочная.
Глобальная область видимости
Когда вы открываете документ в JavaScript и начинаете писать код, вы попадаете в глобальную область видимости.
Все что создается в глобальной области видимости — переменные, функции — доступны из любой точки в программе. Также глобальные переменные доступны все время работы вашего приложения и удаляются только когда программа заканчивает свою работу.
Многие новички поначалу слишком часто используют глобальные переменные — так программировать несколько проще, однако это считается плохой практикой, и часто приводит к нестабильно работающим программам, которые в итоге используют куда больше памяти, чем им на самом деле нужно. Ведь если бы переменные были бы надежно инкапсулированы внутри функций, в которых они используются, по окончанию работы функции они были бы удалены из памяти с помощью сборщика мусора( Garbage collector), и прекратили занимать клиентскую память, которая не бесконечная.
Локальная область видимости
Переменные, которые объявлены локально, доступны только в той области видимости, где они были объявлены.
Самый простой способ создать новую область видимости — это создать новую функцию. Переменная, созданная внутри функции, доступна только изнутри. Кроме того, локальную область видимости можно получить с помощью блочной области видимости(будет разобрано ниже).
function foo(){
let x = 15; }
//console.log(x); error
{
let y = 14; }
// console.log(y); тоже error
{
var z = 13; }
console.log(z); //опять var нам смешивает карты,
//потому что на нем не срабатывает блочная область
//видимости - теперь 13
Лексическая область видимости
Итак, что такое лексическая область видимости? Выражаясь простым языком — это способность внутренней функции получать доступ к внешней области видимости. Здесь стоит обратиться к практике замыканий. О них, наверное, можно написать еще пару статей, но я приведу быстро один классический пример:
sum(5)(5) //как сделать чтобы это работало?
function sum(a){
var add = function(b){
return a+b;
}
return add;
}
console.log(sum(5)(5)); // 10 возможно надо
//отправиться в Хогвартс чтобы это понять
Блочная область видимости
Пока что мы только обсудили области видимости, которые связаны с работой функций и фигурных скобок{}, а различия в работе var и let мы обсудили только косвенно.
Как работает директива var? При объявлении переменной с её помощью в глобальной области видимости имя переменной приписывается как свойство глобальному объекту window(если мы подразумеваем браузер) и остается там все время работы программы. В тоже время как блочная область видимости, такая как {}( и куда вполне логично включаются и if, for, while и все остальные).
Кроме того, есть еще одна особенность let и const — объявленные в одной области видимости, они потом не могут быть объявлены еще раз в этой же( ну недовольство интерпретатора здесь выглядит вполне логично).
let x = 15;
console.log(x); // все отлично
{
let x = 16; // о все по прежнему работает хорошо
console.log(x) // потому как это разные области видимости все работает нормально
let x = 17; // вот теперь у нас интерпретатор сообщит об ошибке, потому что мы переопределили переменную в этой области
}
new Function
Особенности областей видимости при объявлении новой функции как «new Function». Данный вариант создания функции используется достаточно редко, но иногда это может потребоваться.
Пример синтаксиса:
//let newFunc = new Function([arg1, arg2…argN], functionBody);
let mult = new Function(‘a’, ‘b’, ‘return a * b’);
console.log(mult(3,4));
Обычно функция запоминает, где она родилась(Lexical Environment), но когда функция создается с использованием конструкции new Function, в её переменные окружения записываются не окружающие ее переменные, как в обычной ситуации, а только объявленные глобально.
//здесь снова будут замыкания, так что надеюсь вас две ()() подряд уже не удивляют
let a = 3;
function outerFunc() {
var a = 2;
var func = new Function('console.log(a*a)');
return func;
}
outerFunc()(); // 9, из глобального объекта window
Hoisting(поднятие переменных)
Обсуждая области видимости, мы не могли с вами не коснуться темы поднятия области переменных. Интерпретатор, который считывает код, на самом деле читает его два раза: он читает функции, объявленные как function declaraton, и читает глобальные переменных, объявленные глобальные с помощью переменной var. Однако переменным записывается не их объявленные значения, а значение undefined.
console.log(x); // undefined
var x = 15;
console.log(y);// error
let y = 13;
Пускай эта тема относится только косвенно к областям видимости, но иногда эти знания могут пригодиться.
Всем спасибо! Надеюсь, кому-то эта статья была полезной!
Полезные ссылки:
developer.mozilla.org/en-US/docs/Glossary/Scope
developer.mozilla.org/ru/docs/Web/JavaScript/Closures
2ality.com/2015/02/es6-scoping.html
learn.javascript.ru/new-function
habr.com/ru/company/otus/blog/466873
К сожалению, не доступен сервер mySQL