JavaScript – язык программирования, который используется при создании веб-контента. Он предусматривает не только простой синтаксис, но и разнообразные функции. Все это помогает создавать действительно стоящие приложения.
Для того, чтобы быть хорошим разработчиком, необходимо изучить немало особенностей ДжаваСкрипт. Одна из них – это замыкания. Новичков в программировании соответствующая тема способна на первых порах сбить с толку. Но, если разобраться с оной, после выйдет создавать улучшенные программные коды.
Определение понятия
Замыкание – функция, которая обладает доступом к своей внешней функции по области видимости, даже если последняя остановилась. Соответственно, замыкание умеет запоминать и получать доступ к:
И не важно, прекратилась ли выполняться внешняя функция или нет.
Замыкание – функция первого класса, имеющая в своем теле ссылки на переменные, объявленные за пределами соответствующей функции в зоне видимости и не являющиеся ее параметрами. Так называют функцию, ссылаемую на свободные переменные в области видимости.
Замыкание — способ представления функциональности и информации, которые связаны друг с другом. Данный момент сход с экземплярами объектов. Рассматриваемая «операция» — особый вид функции, которая имеет доступ (предопределение) в теле другой функции. Создается каждый раз при выполнения последней.
Лексическая область видимости
Так принято называть статическую область в JS, которая имеет прямое отношение к доступу к переменным, объектам, функциям. В основе лежит расположение соответствующих элементов в программном коде.
Выше представлен пример кода. Его нужно рассмотреть, чтобы лучше разобраться в лексической области видимости. Тут происходит следующее:
- Функция inner обладает доступом к переменным в пределах своей зоны видимости.
- Она же имеет доступ в пределах функции outer, а также глобальной области видимости.
- Функция outer получает доступ к переменным, которые объявлены в собственной и глобальных зонах.
Полученная цепочка обладает следующим представлением:
Обратить внимание необходимо на следующие факты:
- Функция Inner окружена лексической областью outer.
- Последняя окружена глобальной «видимостью».
- У функции inner есть доступ к переменным, которые определены в outer и глобальной видимости.
Но для того, чтобы продолжить тему и лучше понимать замыкания, рассмотрим в статье далее несколько примеров. Они всегда помогают успешно ориентироваться в выбранном направлении.
Примеры на практике
Внутреннее устройство замыканий понять очень трудно, особенно если опираться только на «примерные задачи». Наглядные примеры продемонстрируют нюансы рассматриваемой темы.
Номер один
Ниже представлен элемент программного кода, написанного в Java Script:
Здесь происходит следующее:
- Функция person() отвечает за возврат внутренней функции displayName().
- Происходит сохранение последней в переменную peter.
- После вызывается peter(), где соответствующая переменная содержит на displayName().
- Через консоль происходит ввод имени Peter.
Функция displayName() не обладает переменной с именем name. Из-за этого можно прийти к выводу о том, что соответствующая «операция» способна тем или иным методом получать доступ к переменной, объявленной во внешней по отношению к ней функции, даже когда последняя отработана. Дело все в том, что в приведенном примере displayName() – это замыкание.
Пример два
А вот еще один наглядный пример, который позволяет наглядно увидеть принцип работы рассматриваемой операции:
Здесь происходит следующее:
- В переменной count содержится ссылка на анонимную внутреннюю функцию, которая возвращается посредством getCounter().
- Count() выступает замыканием и может обращаться к одноименной переменной counter.
- Counter находится в getCount().
- Рассматриваемая «операция» может обращаться к переменной counter даже после прекращения работы getCounter().
Значение переменной counter не будет сбрасываться в 0 каждый раз, когда происходит вызов count(). Подобная ситуация возникает из-за того, что при активации соответствующей «операции» осуществляется создание новой области видимости. А для getCounter() имеется всего одна подобная «зона». Переменная counter объявлена в области видимости getCounter, значение оной между вызовом count() будет сохраняться без сброса.
Принцип работы
Настало время рассмотреть замыкания более подробно. Ранее было сказано лишь о том, что это такое, а также приведены наглядные примеры. Внутренние механизмы процесса не затрагивались.
Чтобы лучше понимать замыкания, требуется разобраться с весьма важными концепциями выбранного языка программирования. Речь идет о контексте и лексическом окружении.
О контексте выполнения
Это абстрактное окружение, в котором код JS вычисляется, а затем реализовывается. Здесь важно запомнить следующие моменты:
- При выполнении глобального кода манипуляции осуществляются внутри глобального контекста выполнения.
- Код «операции» будет «инициализироваться» внутри контекста выполнения оной.
- В определенный момент времени может обрабатываться код только в одном контексте выполнения. Связано это с тем, что JS является однопоточным языком.
- Управление процессами происходит через стек вызовов.
Стек вызовов – своеобразная структура информации, которая устроена по принципу LIFO (последний вошел – первым вышел). Новые составляющие помещаются исключительно в верхней части стека. И именно оттуда происходит изъятие оных.
Нынешний контекст выполнения всегда расположен в верхней части стека. Если текущая функция прекращает работать, ее контекст выполнения будет извлекаться из стека. Управление перейдет тому контексту, который был расположен ниже в стеке вызовов.
О процессе наглядно
Используем следующий пример кода, чтобы больше разобраться в стеках вызовов и контексте:
Здесь при выполнении кода:
- Движок создаст глобальный контекст выполнения для обработки глобальной кодификации.
- При встрече с вызовом функции first() будет создан новый контент для выполнения оной.
- Далее полученный контекст будет размещен для соответствующей «операции» в верхней части стека.
Стек вызовов представлен ниже:
При завершении first(), контекст ее выполнения будет извлекаться из стека вызовов. Это дает возможность передачи управления context выполнения, расположенному ниже него. А именно – глобального характера. Далее обрабатывается элемент представленной кодификации, находящийся в глобальной «территории».
Несколько слов о лексическом окружении
Когда JavaScript осуществляет создание контекста выполнения для реализации «операций» или глобальных частей кода, появляется новое лексическое окружение. Оно предназначается для того, чтобы хранить переменные, объявленные в той или иной функции во время обработки оной.
Лексическое окружение – структура информации, несущая в себе сведения о соответствии переменных с идентификаторами. Идентификатором выступает имя переменной или «операции». Переменная – ссылка на объект. Может являться значением примитивного характера.
В лексическом окружении функции содержатся некие составляющие:
- запись окружения – пространство, в котором хранятся объявления «манипуляций» и переменных;
- ссылка на внешнее окружение – своеобразная ссылка, которая позволяет обращаться к родительскому лексическому окружению.
Именно ссылки «внешнего типа» выступают в качестве основополагающей для полноценного понимания замыканий.
Выше представлен элемент кода, который описывает лексическое окружение.
На что стоит поглядеть
Вот код, который поможет лучше освоить «лексику»:
Здесь происходит следующее:
- Движок Джавы будет отвечать за создание глобального контекста выполнения для обработки глобального кода.
- После этого он создает новое лексическое окружения для того, чтобы хранить переменные и «операции», объявленные в глобальной области видимости.
- Результатом окажется лексическое окружение:
- Ссылка на внешнее окружение (outer) стоит в значении null. Связано это с тем, что у глобальной «области видимости» отсутствует «лексика».
- В процессе создания context для first() возникнет и «лексика» для хранения переменных объявленных в пределе оной и образованных при непосредственном выполнении.
- Итог получится таким:
- Ссылка на внешнюю «лексику» устанавливается в значении <globalLexicalEnvironment>. Связано это с тем, что исходный код «операции» расположен в «глобальном пространстве».
Стоит обратить внимание на то, что при завершении работы функции контекст будет извлекаться из стеков вызовов. Лексическое окружение может удаляться из памяти или оставаться в ней далее. Все зависит от существования ссылки на соответствующую «лексику» в виде ссылок на внешнее лексическое окружение в других рассматриваемых областях.
Внешние переменные
Локальные переменные – не единственные, к которым можно обратиться из функции. Дополнительно предусматривается вызов внешних «хранилищ»:
Интерпретатор при доступе к переменной будет в первую очередь пытаться обнаружить переменную в текущем LexicalEnvironment. Лишь после этого, при условии отсутствии оной – во внешнем объекте «хранилищ». В приведенном примере таковым выступает windows.
Подобное явление становится доступным из-за того, что ссылка на внешний объект переменных будет храниться в специальном свойстве функции внутреннего характера. А именно – в [[Scope]]. Оно не имеет прямого доступа, но это не значит, что программер должен обходить стороной оную. Знать принципы работы «Скоп» важно при программировании на JS.
Интерпретатор при создании «операции» создает для этой функции скрытое свойство [[Scope]]. Оно будет ссылаться на лексическое окружение, в котором оная создавалась.
Пример выше предусматривает такие явления:
- Упомянутый ранее окружением выступает window, что приводит к образованию свойства:
- Оное будет неизменным. Следует за «операцией», привязывая ее к своему месту рождения.
- После запуска ее объект переменных LocalEnvironment получит ссылку на внешнюю «лексику» со значением из «Скоп».
- Когда переменная не будет обнаружена в «манипуляции», произойдет ее поиск во внешней среде.
Вывод к внешней переменной происходит за счет alert (username) за счет описанных принципов. В коде все это имеет интерпретацию поиска во внешней области видимости, за пределами функции.
Важные выводы и внешние переменные
В результате изученной информации можно сделать следующие заключения:
- Каждая «операция» будет при создании получать ссылку [[Scope]] на объект с переменными, в контексте которого она появилась.
- После запуска создается новый объект с «хранилищами» LexicalEnvironment. Он получит ссылку на внешний объект переменных из [[Scope]].
- Во время поиска переменных оный произойдет сначала внутри текущего объекта переменных, лишь после – по соответствующей ссылке.
На первых порах подобная информация может показаться сложной. Но она позволяет разобраться в более важных для программиста вещах.
Функции – кратко о самом важном
Замыкания в JS напрямую связаны с функциями. В них объявляются не только локальные переменные, но и другие «операции». А значит, целесообразно говорить о вложенности. Такой прием позволяет намного проще реализовывать некоторые программные коды.
Вложенные функции – как применять
Вот пример кода:
Он поможет разобраться с эффективным применением вложенных функций при замыканиях. Он предусматривает такие моменты:
- getFullName() – вспомогательная «операция».
- Вложенные «манипуляции» получают [[Scope]] вместе с глобальными:
- Соответствующий прием обеспечит получение getFullName() снаружи lastName и firstName.
Стоит обратить внимание на то, что при отсутствии рассматриваемой переменной во внешнем объекте, она будет искаться в «более внешнем» через [[Scope]] внешней «операции».
Указанная ранее информация ведет к тому, что последний пример кода (выше) будет успешно работать.
Возврат – return function
Но есть и более сложные ситуации. Пример – внутри одной «операции» будет создана другая, после чего система выведет оную в виде итогового результата. Такая манипуляция рассматривается при создании интерфейсов как «обычная». В виде «операции» может выступать обработчик действий клиента.
Рассматриваемый случай предусматривает счетчик-«манипуляцию», которая будет считывать собственные вызовы. Он возвращает текущее количество оных.
Выше makeCounter будет создавать счетчик. Результат – два независимых «элемента» — counter и counter2. Каждый из них незаметно отвечает за сохранение количество вызовов в переменной внешнего типа currentCount. Ей обладает каждый счетчик.
Что здесь происходит
Если рассмотреть кодификацию подробно, будет происходить следующее:
- В строчке (*) запустится makeCounter, создастся LexicalEnvironment для переменных нынешнего вызова. У «операции» лишь одна переменная под названием var currentCount. Она выступит свойством соответствующего объекта. Сначала инициализируется в undefined, после обработки ей будет присвоено значение 1.
- Когда будет обрабатываться makeCounter, произойдет создание «операции» в строчке (**), что приведет к присваиванию внутреннего свойства [[Scope]]. Она получит ссылку на нынешнее LexicalEnvironment.
- Вызов «МейкКантер» завершается. «Манипуляция» (**) будет возвращена и сохранена во внешней переменной counter (*).
- В counter запишется «операция»:
- Counter, возвращенная из «МейкКантер» будет помнить об окружении, в котором возникла. Это происходит за счет «Скоп».
- При вызове counter неизвестно, что произойдет, так как она содержит всего одну строку – с return. Собственные объект переменных (LE) окажется пустым.
- За счет свойства [[Scope]] указывается внешнее окружение. Для увеличения и возврата currentCount интерпретатор будет искать в нынешнем объекте переменных LE. Оные не обнаружатся.
- Осуществляется переход на внешний объект, где «предмет розыска» будет обнаружен, изменен и возвращен:
Переменные во внешних областях видимости удается не только считывать, но и корректировать.
Приведенный пример в console продемонстрировал независимость взаимного характера имеющихся счетчиков. Это из-за того, что при активации makeCounter будет создаваться собственный объект переменных LE с «личными» свойствами currentCount. Именно на него очередной счетчик будет получать ссылку [[Scope]].
Как быстро освоить тему
Изучая замыкание, можно легко запутаться. Это приводит к тому, что разобраться с выбранным направлением оказывается весьма проблематично. Но выход есть всегда – это дистанционные тематические курсы.
Срок обучения – от нескольких месяцев до года. Предложения для начинающих и опытных разработчиков. Гарантирована практика, а также контакты с опытными разработчиками. Можно в кратчайшие сроки выучить несколько языков программирования и углубиться в них. В конце обучения выдается электронный сертификат, подтверждающий знания.
<!DOCTYPE html>
<html dir="ltr" lang="ru-RU">
<head>
<meta charset="UTF-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="profile" href="http://gmpg.org/xfn/11" />
<title>Замыкания в JavaScript: как не наделать ошибок OTUS</title>
<!-- All in One SEO 4.5.2.1 - aioseo.com -->
<meta name="description" content="JavaScript – язык программирования, который используется при создании веб-контента. Он предусматривает не только простой синтаксис, но и разнообразные функции. Все это помогает создавать действительно стоящие приложения. Для того, чтобы быть хорошим разработчиком, необходимо изучить немало особенностей ДжаваСкрипт. Одна из них – это замыкания. Новичков в программировании соответствующая тема способна на первых порах сбить с толку." />
<meta name="robots" content="max-image-preview:large" />
<link rel="canonical" href="https://otus.ru/journal/zamykaniya-v-javascript-kak-ne-nadelat-oshibok/" />
<meta name="generator" content="All in One SEO (AIOSEO) 4.5.2.1" />
<script type="application/ld+json" class="aioseo-schema">
{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#article","name":"\u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u0432 JavaScript: \u043a\u0430\u043a \u043d\u0435 \u043d\u0430\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u043a OTUS","headline":"\u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u0432 JavaScript: \u043a\u0430\u043a \u043d\u0435 \u043d\u0430\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u043a","author":{"@id":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/#author"},"publisher":{"@id":"https:\/\/otus.ru\/journal\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/otus.ru\/journal\/wp-content\/uploads\/2022\/02\/oj-1080x720-1-1.png","width":1080,"height":720},"datePublished":"2022-02-03T17:32:31+00:00","dateModified":"2022-02-03T17:32:33+00:00","inLanguage":"ru-RU","mainEntityOfPage":{"@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#webpage"},"isPartOf":{"@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#webpage"},"articleSection":"\u041f\u043e\u043b\u0435\u0437\u043d\u043e\u0435, JavaScript"},{"@type":"BreadcrumbList","@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/otus.ru\/journal\/#listItem","position":1,"name":"\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430","item":"https:\/\/otus.ru\/journal\/","nextItem":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#listItem"},{"@type":"ListItem","@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#listItem","position":2,"name":"\u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u0432 JavaScript: \u043a\u0430\u043a \u043d\u0435 \u043d\u0430\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u043a","previousItem":"https:\/\/otus.ru\/journal\/#listItem"}]},{"@type":"Organization","@id":"https:\/\/otus.ru\/journal\/#organization","name":"\u041e\u0442\u0443\u0441 \u043e\u043d\u043b\u0430\u0439\u043d-\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435","url":"https:\/\/otus.ru\/journal\/","sameAs":["https:\/\/www.youtube.com\/channel\/UCetgtvy93o3i3CvyGXKFU3g"],"contactPoint":{"@type":"ContactPoint","telephone":"+74999389202","contactType":"Customer Support"}},{"@type":"Person","@id":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/#author","url":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/","name":"A. Pavlenko","image":{"@type":"ImageObject","@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/d4c499a104d7c2522fa41f89e6819499?s=96&d=mm&r=g","width":96,"height":96,"caption":"A. Pavlenko"}},{"@type":"WebPage","@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#webpage","url":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/","name":"\u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u0432 JavaScript: \u043a\u0430\u043a \u043d\u0435 \u043d\u0430\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u043a OTUS","description":"JavaScript \u2013 \u044f\u0437\u044b\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0432\u0435\u0431-\u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041e\u043d \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043d\u043e \u0438 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0412\u0441\u0435 \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u043d\u0435\u043c\u0430\u043b\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0414\u0436\u0430\u0432\u0430\u0421\u043a\u0440\u0438\u043f\u0442. \u041e\u0434\u043d\u0430 \u0438\u0437 \u043d\u0438\u0445 \u2013 \u044d\u0442\u043e \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f. \u041d\u043e\u0432\u0438\u0447\u043a\u043e\u0432 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0442\u0435\u043c\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u0430 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0445 \u043f\u043e\u0440\u0430\u0445 \u0441\u0431\u0438\u0442\u044c \u0441 \u0442\u043e\u043b\u043a\u0443.","inLanguage":"ru-RU","isPartOf":{"@id":"https:\/\/otus.ru\/journal\/#website"},"breadcrumb":{"@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#breadcrumblist"},"author":{"@id":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/#author"},"creator":{"@id":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/otus.ru\/journal\/wp-content\/uploads\/2022\/02\/oj-1080x720-1-1.png","@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#mainImage","width":1080,"height":720},"primaryImageOfPage":{"@id":"https:\/\/otus.ru\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/#mainImage"},"datePublished":"2022-02-03T17:32:31+00:00","dateModified":"2022-02-03T17:32:33+00:00"},{"@type":"WebSite","@id":"https:\/\/otus.ru\/journal\/#website","url":"https:\/\/otus.ru\/journal\/","name":"OTUS JOURNAL","description":"Blog about IT","inLanguage":"ru-RU","publisher":{"@id":"https:\/\/otus.ru\/journal\/#organization"}}]}
</script>
<!-- All in One SEO -->
<link rel='dns-prefetch' href='//otus.ru' />
<link rel='dns-prefetch' href='//fonts.googleapis.com' />
<link rel='stylesheet' id='wp-block-library-css' href='https://otus.ru/journal/wp-includes/css/dist/block-library/style.min.css?ver=6.4.7' type='text/css' media='all' />
<style id='classic-theme-styles-inline-css' type='text/css'>
/*! This file is auto-generated */
.wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none}
</style>
<style id='global-styles-inline-css' type='text/css'>
body{--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1);--wp--preset--shadow--crisp: 6px 6px 0px rgba(0, 0, 0, 1);}:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}
.wp-block-navigation a:where(:not(.wp-element-button)){color: inherit;}
:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}
:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}
.wp-block-pullquote{font-size: 1.5em;line-height: 1.6;}
</style>
<link rel='stylesheet' id='wbcr-comments-plus-url-span-css' href='https://otus.ru/journal/wp-content/plugins/clearfy/components/comments-plus/assets/css/url-span.css?ver=2.2.0' type='text/css' media='all' />
<link rel='stylesheet' id='wpel-style-css' href='https://otus.ru/journal/wp-content/plugins/wp-external-links/public/css/wpel.css?ver=2.59' type='text/css' media='all' />
<link rel='stylesheet' id='ez-toc-css' href='https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/assets/css/screen.min.css?ver=2.0.61' type='text/css' media='all' />
<style id='ez-toc-inline-css' type='text/css'>
div#ez-toc-container .ez-toc-title {font-size: 120%;}div#ez-toc-container .ez-toc-title {font-weight: 500;}div#ez-toc-container ul li {font-size: 95%;}div#ez-toc-container nav ul ul li {font-size: 90%;}
.ez-toc-container-direction {direction: ltr;}.ez-toc-counter ul{counter-reset: item ;}.ez-toc-counter nav ul li a::before {content: counters(item, ".", decimal) ". ";display: inline-block;counter-increment: item;flex-grow: 0;flex-shrink: 0;margin-right: .2em; float: left; }.ez-toc-widget-direction {direction: ltr;}.ez-toc-widget-container ul{counter-reset: item ;}.ez-toc-widget-container nav ul li a::before {content: counters(item, ".", decimal) ". ";display: inline-block;counter-increment: item;flex-grow: 0;flex-shrink: 0;margin-right: .2em; float: left; }
</style>
<link rel='stylesheet' id='contentberg-fonts-css' href='https://fonts.googleapis.com/css?family=Roboto%3A400%2C500%2C700%7CPT+Serif%3A400%2C400i%2C600%7CIBM+Plex+Serif%3A500' type='text/css' media='all' />
<link rel='stylesheet' id='contentberg-core-css' href='https://otus.ru/journal/wp-content/themes/contentberg/style.css?ver=1.8.3' type='text/css' media='all' />
<link rel='stylesheet' id='contentberg-lightbox-css' href='https://otus.ru/journal/wp-content/themes/contentberg/css/lightbox.css?ver=1.8.3' type='text/css' media='all' />
<link rel='stylesheet' id='font-awesome-css' href='https://otus.ru/journal/wp-content/themes/contentberg/css/fontawesome/css/font-awesome.min.css?ver=1.8.3' type='text/css' media='all' />
<script type="text/javascript" id="breeze-prefetch-js-extra">
/* <![CDATA[ */
var breeze_prefetch = {"local_url":"https:\/\/otus.ru\/journal","ignore_remote_prefetch":"1","ignore_list":["\/wp-admin\/"]};
/* ]]> */
</script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/breeze/assets/js/js-front-end/breeze-prefetch-links.min.js" id="breeze-prefetch-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/jquery/jquery.min.js" id="jquery-core-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/jquery/jquery-migrate.min.js" id="jquery-migrate-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/lazysizes.js" id="lazysizes-js"></script>
<link rel="https://api.w.org/" href="https://otus.ru/journal/wp-json/" /><link rel="alternate" type="application/json" href="https://otus.ru/journal/wp-json/wp/v2/posts/2776" /><link rel='shortlink' href='https://otus.ru/journal/?p=2776' />
<link rel="alternate" type="application/json+oembed" href="https://otus.ru/journal/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fotus.ru%2Fjournal%2Fzamykaniya-v-javascript-kak-ne-nadelat-oshibok%2F" />
<link rel="alternate" type="text/xml+oembed" href="https://otus.ru/journal/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fotus.ru%2Fjournal%2Fzamykaniya-v-javascript-kak-ne-nadelat-oshibok%2F&format=xml" />
<script>var Sphere_Plugin = {"ajaxurl":"https:\/\/otus.ru\/journal\/wp-admin\/admin-ajax.php"};</script><link rel="icon" href="https://otus.ru/journal/wp-content/uploads/2020/11/cropped-OTUS_logo_OTUS-COMP-LOGO-WHITE-1-32x32.png" sizes="32x32" />
<link rel="icon" href="https://otus.ru/journal/wp-content/uploads/2020/11/cropped-OTUS_logo_OTUS-COMP-LOGO-WHITE-1-192x192.png" sizes="192x192" />
<link rel="apple-touch-icon" href="https://otus.ru/journal/wp-content/uploads/2020/11/cropped-OTUS_logo_OTUS-COMP-LOGO-WHITE-1-180x180.png" />
<meta name="msapplication-TileImage" content="https://otus.ru/journal/wp-content/uploads/2020/11/cropped-OTUS_logo_OTUS-COMP-LOGO-WHITE-1-270x270.png" />
<style type="text/css" id="wp-custom-css">
#menu-item-10406 .wpel-icon {
display: none;
}
#menu-item-10407 .wpel-icon {
display: none;
}
.otus-login-site a .wpel-icon {
display: none;
}
.menu-menju-navykov-container a .wpel-icon {
display: none;
}
.otus-login-site a
{
background: #ffd709;
border-radius: 12px;
color: #0f0f10;
font-size: 14px;
font-weight: 700;
line-height: 20px;
display: block;
text-align: center;
padding: 8px 25px;
}
.main-footer.dark {
background: linear-gradient(90deg, #a64fc5, #4f54e6);
border-color: transparent;
}
.main-footer.bold .copyright {
color: #fff;
}
.main-footer.bold .to-top i {
color: #fff;
}
.main-footer.bold .back-to-top {
color: #fff;
}
.nav__scroll {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.scrollable-menu .menu {
display: flex;
}
.nav__scroll
{
background: linear-gradient(90deg, #a64fc5, #4f54e6);
}
.scrollable-menu .menu .menu-item {
flex: 0 0 auto;
padding: 15px 15px;
}
.scrollable-menu .menu .menu-item a {
color: #fff;
}
.nav__scroll::-webkit-scrollbar{background-color:#fff;height:5px;}
.nav__scroll::-webkit-scrollbar-thumb{background-color:#dcdcdc;}
.nav__scroll::-webkit-scrollbar-track{-webkit-border-radius:0;border-radius:0;background-color:#fff;}/
body {
min-width: 320px;
}
.banner-click img {
margin: 0 auto;
display: block;
}
.banner-click {
cursor: pointer;
}
.banner-footer-area {
margin-bottom: 20px;
}
.banner-left-area {
margin-top: 40px;
} </style>
<!--Start VDZ Yandex Metrika Plugin-->
<!-- Yandex.Metrika counter --><script type="text/javascript" >(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");ym(34531570, "init", {clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true, trackHash:true, ecommerce:"dataLayer"});</script>
<noscript><div><img src="https://mc.yandex.ru/watch/34531570" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter --><!--START ADD EVENTS FROM CF7--><script type='text/javascript'>document.addEventListener( 'wpcf7submit', function( event ) {
//event.detail.contactFormId;
if(ym){
//console.log(event.detail);
ym(34531570, 'reachGoal', 'VDZ_SEND_CONTACT_FORM_7');
ym(34531570, 'params', {
page_url: window.location.href,
status: event.detail.status,
locale: event.detail.contactFormLocale,
form_id: event.detail.contactFormId,
});
}
}, false );
</script><!--END ADD EVENTS FROM CF7-->
<!--End VDZ Yandex Metrika Plugin-->
</head>
<body class="post-template-default single single-post postid-2776 single-format-standard right-sidebar lazy-normal has-lb">
<div class="main-wrap">
<header id="main-head" class="main-head head-nav-below has-search-modal simple simple-boxed">
<div class="inner inner-head" data-sticky-bar="0">
<div class="wrap cf wrap-head">
<div class="left-contain">
<span class="mobile-nav"><i class="fa fa-bars"></i></span>
<div class="title">
<a href="https://otus.ru/journal/" title="OTUS JOURNAL" rel="home" data-wpel-link="internal">
<span class="text-logo"><img src="/journal/wp-content/themes/contentberg/img/logo_site.svg" alt="OTUS JOURNAL"></span>
</a>
</div>
</div>
<div class="navigation-wrap inline">
<nav class="navigation inline simple light" data-sticky-bar="0">
<div class="menu-rubriki-container"><ul id="menu-rubriki" class="menu"><li id="menu-item-109" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-cat-1 menu-item-109"><a href="https://otus.ru/journal/category/pro-it/" data-wpel-link="internal"><span>Про IT</span></a></li>
<li id="menu-item-113" class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor current-menu-parent current-post-parent menu-cat-4 menu-item-113"><a href="https://otus.ru/journal/category/polza/" data-wpel-link="internal"><span>Полезное</span></a></li>
<li id="menu-item-114" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-cat-3 menu-item-114"><a href="https://otus.ru/journal/category/lifestyle/" data-wpel-link="internal"><span>Лайфстайл</span></a></li>
<li id="menu-item-10406" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10406"><a href="https://otus.ru/catalog/courses" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><span>Обучение</span><span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10407" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10407"><a href="https://otus.ru/about" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><span>Информация</span><span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
</ul></div> </nav>
</div>
<div class="actions">
<div class="otus-login-site">
<a href="https://otus.ru/login/" target="_blank" data-wpel-link="external" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Войти<span class="wpel-icon wpel-image wpel-icon-6"></span></a>
</div>
<a href="#" title="Search" class="search-link"><i class="fa fa-search"></i></a>
</div>
</div>
</div>
</header> <!-- .main-head -->
<div class="nav nav_disable nav_colored nav_transparent course-categories__nav nav__scroll ">
<div class="container wrap">
<div class="links inline simple light scrollable-menu">
<div class="menu-menju-navykov-container"><ul id="menu-menju-navykov" class="menu"><li id="menu-item-10413" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10413"><a href="https://otus.ru/categories/programming/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Программирование<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10414" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10414"><a href="https://otus.ru/categories/architecture/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Архитектура<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10415" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10415"><a href="https://otus.ru/categories/operations/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Инфраструктура<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10416" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10416"><a href="https://otus.ru/categories/information-security-courses/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Безопасность<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10417" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10417"><a href="https://otus.ru/categories/data-science/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Data Science<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10418" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10418"><a href="https://otus.ru/categories/gamedev/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">GameDev<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10419" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10419"><a href="https://otus.ru/categories/marketing-business/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Управление<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10420" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10420"><a href="https://otus.ru/categories/analytics/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Аналитика и анализ<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10421" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10421"><a href="https://otus.ru/categories/testing/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Тестирование<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
</ul></div> </div>
</div>
</div>
<div class="main wrap">
<div class="ts-row cf">
<div class="col-8 main-content cf">
<article id="post-2776" class="the-post post-2776 post type-post status-publish format-standard has-post-thumbnail category-polza tag-javascript">
<header class="post-header the-post-header cf">
<div class="post-meta the-post-meta">
<span class="post-cat">
<a href="https://otus.ru/journal/category/polza/" class="category" data-wpel-link="internal">Полезное</a>
</span>
<h1 class="post-title">
Замыкания в JavaScript: как не наделать ошибок
</h1>
<a href="https://otus.ru/journal/zamykaniya-v-javascript-kak-ne-nadelat-oshibok/" class="date-link" data-wpel-link="internal"><time class="post-date">3 февраля, 2022</time></a>
</div>
<div class="featured">
<a href="https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-1.png" class="image-link" data-wpel-link="internal"><img width="770" height="515" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20770%20515%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="attachment-contentberg-main size-contentberg-main lazyload wp-post-image" alt="Замыкания в JavaScript: как не наделать ошибок" title="Замыкания в JavaScript: как не наделать ошибок" decoding="async" fetchpriority="high" data-srcset="https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-1-770x515.png 770w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-1-300x200.png 300w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-1-1024x683.png 1024w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-1-150x100.png 150w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-1-270x180.png 270w" data-src="https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-1-770x515.png" data-sizes="(max-width: 770px) 100vw, 770px" /> </a>
</div>
</header><!-- .post-header -->
<div class="post-content description cf entry-content content-normal">
<div id="ez-toc-container" class="ez-toc-v2_0_61 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction">
<div class="ez-toc-title-container">
<p class="ez-toc-title " >Содержание</p>
<span class="ez-toc-title-toggle"><a href="#" class="ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle" aria-label="Toggle Table of Content"><span class="ez-toc-js-icon-con"><span class=""><span class="eztoc-hide" style="display:none;">Toggle</span><span class="ez-toc-icon-toggle-span"><svg style="fill: #999;color:#999" xmlns="http://www.w3.org/2000/svg" class="list-377408" width="20px" height="20px" viewBox="0 0 24 24" fill="none"><path d="M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z" fill="currentColor"></path></svg><svg style="fill: #999;color:#999" class="arrow-unsorted-368013" xmlns="http://www.w3.org/2000/svg" width="10px" height="10px" viewBox="0 0 24 24" version="1.2" baseProfile="tiny"><path d="M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z"/></svg></span></span></span></a></span></div>
<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-1" href="#%D0%9E%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D0%BE%D0%BD%D1%8F%D1%82%D0%B8%D1%8F" title="Определение понятия">Определение понятия</a></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-2" href="#%D0%9B%D0%B5%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%BE%D0%B1%D0%BB%D0%B0%D1%81%D1%82%D1%8C_%D0%B2%D0%B8%D0%B4%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8" title="Лексическая область видимости">Лексическая область видимости</a></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-3" href="#%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B_%D0%BD%D0%B0_%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D0%B5" title="Примеры на практике">Примеры на практике</a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-4" href="#%D0%9D%D0%BE%D0%BC%D0%B5%D1%80_%D0%BE%D0%B4%D0%B8%D0%BD" title="Номер один">Номер один</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-5" href="#%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_%D0%B4%D0%B2%D0%B0" title="Пример два">Пример два</a></li></ul></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-6" href="#%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B" title="Принцип работы">Принцип работы</a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-7" href="#%D0%9E_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%B5_%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F" title="О контексте выполнения">О контексте выполнения</a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class="ez-toc-link ez-toc-heading-8" href="#%D0%9E_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%B5_%D0%BD%D0%B0%D0%B3%D0%BB%D1%8F%D0%B4%D0%BD%D0%BE" title="О процессе наглядно">О процессе наглядно</a></li></ul></li></ul></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-9" href="#%D0%9D%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2_%D0%BE_%D0%BB%D0%B5%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%BC_%D0%BE%D0%BA%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D0%B8" title="Несколько слов о лексическом окружении">Несколько слов о лексическом окружении</a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-10" href="#%D0%9D%D0%B0_%D1%87%D1%82%D0%BE_%D1%81%D1%82%D0%BE%D0%B8%D1%82_%D0%BF%D0%BE%D0%B3%D0%BB%D1%8F%D0%B4%D0%B5%D1%82%D1%8C" title="На что стоит поглядеть">На что стоит поглядеть</a></li></ul></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-11" href="#%D0%92%D0%BD%D0%B5%D1%88%D0%BD%D0%B8%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5" title="Внешние переменные">Внешние переменные</a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-12" href="#%D0%92%D0%B0%D0%B6%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D1%8B_%D0%B8_%D0%B2%D0%BD%D0%B5%D1%88%D0%BD%D0%B8%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5" title="Важные выводы и внешние переменные">Важные выводы и внешние переменные</a></li></ul></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-13" href="#%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8_%E2%80%93_%D0%BA%D1%80%D0%B0%D1%82%D0%BA%D0%BE_%D0%BE_%D1%81%D0%B0%D0%BC%D0%BE%D0%BC_%D0%B2%D0%B0%D0%B6%D0%BD%D0%BE%D0%BC" title="Функции – кратко о самом важном">Функции – кратко о самом важном</a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-14" href="#%D0%92%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8_%E2%80%93_%D0%BA%D0%B0%D0%BA_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D1%8F%D1%82%D1%8C" title="Вложенные функции – как применять">Вложенные функции – как применять</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-15" href="#%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%82_%E2%80%93_return_function" title="Возврат – return function">Возврат – return function</a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class="ez-toc-link ez-toc-heading-16" href="#%D0%A7%D1%82%D0%BE_%D0%B7%D0%B4%D0%B5%D1%81%D1%8C_%D0%BF%D1%80%D0%BE%D0%B8%D1%81%D1%85%D0%BE%D0%B4%D0%B8%D1%82" title="Что здесь происходит">Что здесь происходит</a></li></ul></li></ul></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-17" href="#%D0%9A%D0%B0%D0%BA_%D0%B1%D1%8B%D1%81%D1%82%D1%80%D0%BE_%D0%BE%D1%81%D0%B2%D0%BE%D0%B8%D1%82%D1%8C_%D1%82%D0%B5%D0%BC%D1%83" title="Как быстро освоить тему">Как быстро освоить тему</a></li></ul></nav></div>
<p>JavaScript – язык программирования, который используется при создании веб-контента. Он предусматривает не только простой синтаксис, но и разнообразные функции. Все это помогает создавать действительно стоящие приложения.</p>
<p>Для того, чтобы быть хорошим разработчиком, необходимо изучить немало особенностей ДжаваСкрипт. Одна из них – это замыкания. Новичков в программировании соответствующая тема способна на первых порах сбить с толку. Но, если разобраться с оной, после выйдет создавать улучшенные программные коды.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9E%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D0%BE%D0%BD%D1%8F%D1%82%D0%B8%D1%8F"></span>Определение понятия<span class="ez-toc-section-end"></span></h2>
<p>Замыкание – функция, которая обладает доступом к своей внешней функции по области видимости, даже если последняя остановилась. Соответственно, замыкание умеет запоминать и получать доступ к:</p>
<ul><li>переменным;</li><li>аргументам.</li></ul>
<p>И не важно, прекратилась ли выполняться внешняя функция или нет.</p>
<p>Замыкание – функция первого класса, имеющая в своем теле ссылки на переменные, объявленные за пределами соответствующей функции в зоне видимости и не являющиеся ее параметрами. Так называют функцию, ссылаемую на свободные переменные в области видимости.</p>
<p>Замыкание — способ представления функциональности и информации, которые связаны друг с другом. Данный момент сход с экземплярами объектов. Рассматриваемая «операция» — особый вид функции, которая имеет доступ (предопределение) в теле другой функции. Создается каждый раз при выполнения последней.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9B%D0%B5%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%BE%D0%B1%D0%BB%D0%B0%D1%81%D1%82%D1%8C_%D0%B2%D0%B8%D0%B4%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8"></span>Лексическая область видимости<span class="ez-toc-section-end"></span></h2>
<p>Так принято называть статическую область в JS, которая имеет прямое отношение к доступу к переменным, объектам, функциям. В основе лежит расположение соответствующих элементов в программном коде.</p>
<figure class="wp-block-image size-large"><img decoding="async" width="530" height="329" src="https://otus.ru/journal/wp-content/uploads/2022/02/1-1.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2779" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/1-1.jpg 530w, https://otus.ru/journal/wp-content/uploads/2022/02/1-1-300x186.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/1-1-150x93.jpg 150w" sizes="(max-width: 530px) 100vw, 530px" /></figure>
<p>Выше представлен пример кода. Его нужно рассмотреть, чтобы лучше разобраться в лексической области видимости. Тут происходит следующее:</p>
<ol type="1"><li>Функция inner обладает доступом к переменным в пределах своей зоны видимости.</li><li>Она же имеет доступ в пределах функции outer, а также глобальной области видимости.</li><li>Функция outer получает доступ к переменным, которые объявлены в собственной и глобальных зонах.</li></ol>
<p>Полученная цепочка обладает следующим представлением:</p>
<figure class="wp-block-image size-large"><img decoding="async" width="334" height="122" src="https://otus.ru/journal/wp-content/uploads/2022/02/2-1.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2780" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/2-1.jpg 334w, https://otus.ru/journal/wp-content/uploads/2022/02/2-1-300x110.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/2-1-150x55.jpg 150w" sizes="(max-width: 334px) 100vw, 334px" /></figure>
<p>Обратить внимание необходимо на следующие факты:</p>
<ol type="1"><li>Функция Inner окружена лексической областью outer.</li><li>Последняя окружена глобальной «видимостью».</li><li>У функции inner есть доступ к переменным, которые определены в outer и глобальной видимости.</li></ol>
<p>Но для того, чтобы продолжить тему и лучше понимать замыкания, рассмотрим в статье далее несколько примеров. Они всегда помогают успешно ориентироваться в выбранном направлении.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B_%D0%BD%D0%B0_%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D0%B5"></span>Примеры на практике<span class="ez-toc-section-end"></span></h2>
<p>Внутреннее устройство замыканий понять очень трудно, особенно если опираться только на «примерные задачи». Наглядные примеры продемонстрируют нюансы рассматриваемой темы.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9D%D0%BE%D0%BC%D0%B5%D1%80_%D0%BE%D0%B4%D0%B8%D0%BD"></span>Номер один<span class="ez-toc-section-end"></span></h3>
<p>Ниже представлен элемент программного кода, написанного в Java Script:</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="340" height="207" src="https://otus.ru/journal/wp-content/uploads/2022/02/3.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2781" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/3.jpg 340w, https://otus.ru/journal/wp-content/uploads/2022/02/3-300x183.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/3-150x91.jpg 150w" sizes="(max-width: 340px) 100vw, 340px" /></figure>
<p>Здесь происходит следующее:</p>
<ol type="1"><li>Функция person() отвечает за возврат внутренней функции displayName().</li><li>Происходит сохранение последней в переменную peter.</li><li>После вызывается peter(), где соответствующая переменная содержит на displayName().</li><li>Через консоль происходит ввод имени Peter.</li></ol>
<p>Функция displayName() не обладает переменной с именем name. Из-за этого можно прийти к выводу о том, что соответствующая «операция» способна тем или иным методом получать доступ к переменной, объявленной во внешней по отношению к ней функции, даже когда последняя отработана. Дело все в том, что в приведенном примере displayName() – это замыкание.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_%D0%B4%D0%B2%D0%B0"></span>Пример два<span class="ez-toc-section-end"></span></h3>
<p>А вот еще один наглядный пример, который позволяет наглядно увидеть принцип работы рассматриваемой операции:</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="408" height="229" src="https://otus.ru/journal/wp-content/uploads/2022/02/4.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2782" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/4.jpg 408w, https://otus.ru/journal/wp-content/uploads/2022/02/4-300x168.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/4-150x84.jpg 150w" sizes="(max-width: 408px) 100vw, 408px" /></figure>
<p>Здесь происходит следующее:</p>
<ol type="1"><li>В переменной count содержится ссылка на анонимную внутреннюю функцию, которая возвращается посредством getCounter().</li><li>Count() выступает замыканием и может обращаться к одноименной переменной counter.</li><li>Counter находится в getCount().</li><li>Рассматриваемая «операция» может обращаться к переменной counter даже после прекращения работы getCounter().</li></ol>
<p>Значение переменной counter не будет сбрасываться в 0 каждый раз, когда происходит вызов count(). Подобная ситуация возникает из-за того, что при активации соответствующей «операции» осуществляется создание новой области видимости. А для getCounter() имеется всего одна подобная «зона». Переменная counter объявлена в области видимости getCounter, значение оной между вызовом count() будет сохраняться без сброса.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B"></span>Принцип работы<span class="ez-toc-section-end"></span></h2>
<p>Настало время рассмотреть замыкания более подробно. Ранее было сказано лишь о том, что это такое, а также приведены наглядные примеры. Внутренние механизмы процесса не затрагивались.</p>
<p>Чтобы лучше понимать замыкания, требуется разобраться с весьма важными концепциями выбранного языка программирования. Речь идет о контексте и лексическом окружении.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9E_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%B5_%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F"></span>О контексте выполнения<span class="ez-toc-section-end"></span></h3>
<p>Это абстрактное окружение, в котором код JS вычисляется, а затем реализовывается. Здесь важно запомнить следующие моменты:</p>
<ol type="1"><li>При выполнении глобального кода манипуляции осуществляются внутри глобального контекста выполнения.</li><li>Код «операции» будет «инициализироваться» внутри контекста выполнения оной.</li><li>В определенный момент времени может обрабатываться код только в одном контексте выполнения. Связано это с тем, что JS является однопоточным языком.</li><li>Управление процессами происходит через стек вызовов.</li></ol>
<p>Стек вызовов – своеобразная структура информации, которая устроена по принципу LIFO (последний вошел – первым вышел). Новые составляющие помещаются исключительно в верхней части стека. И именно оттуда происходит изъятие оных.</p>
<p>Нынешний контекст выполнения всегда расположен в верхней части стека. Если текущая функция прекращает работать, ее контекст выполнения будет извлекаться из стека. Управление перейдет тому контексту, который был расположен ниже в стеке вызовов.</p>
<h4 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9E_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%B5_%D0%BD%D0%B0%D0%B3%D0%BB%D1%8F%D0%B4%D0%BD%D0%BE"></span>О процессе наглядно<span class="ez-toc-section-end"></span></h4>
<p>Используем следующий пример кода, чтобы больше разобраться в стеках вызовов и контексте:</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="635" height="365" src="https://otus.ru/journal/wp-content/uploads/2022/02/5.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2783" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/5.jpg 635w, https://otus.ru/journal/wp-content/uploads/2022/02/5-300x172.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/5-150x86.jpg 150w" sizes="(max-width: 635px) 100vw, 635px" /></figure>
<p>Здесь при выполнении кода:</p>
<ol type="1"><li>Движок создаст глобальный контекст выполнения для обработки глобальной кодификации.</li><li>При встрече с вызовом функции first() будет создан новый контент для выполнения оной.</li><li>Далее полученный контекст будет размещен для соответствующей «операции» в верхней части стека.</li></ol>
<p>Стек вызовов представлен ниже:</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="666" height="189" src="https://otus.ru/journal/wp-content/uploads/2022/02/6.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2784" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/6.jpg 666w, https://otus.ru/journal/wp-content/uploads/2022/02/6-300x85.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/6-150x43.jpg 150w" sizes="(max-width: 666px) 100vw, 666px" /></figure>
<p>При завершении first(), контекст ее выполнения будет извлекаться из стека вызовов. Это дает возможность передачи управления context выполнения, расположенному ниже него. А именно – глобального характера. Далее обрабатывается элемент представленной кодификации, находящийся в глобальной «территории».</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9D%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2_%D0%BE_%D0%BB%D0%B5%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%BC_%D0%BE%D0%BA%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D0%B8"></span>Несколько слов о лексическом окружении<span class="ez-toc-section-end"></span></h2>
<p>Когда JavaScript осуществляет создание контекста выполнения для реализации «операций» или глобальных частей кода, появляется новое лексическое окружение. Оно предназначается для того, чтобы хранить переменные, объявленные в той или иной функции во время обработки оной.</p>
<p>Лексическое окружение – структура информации, несущая в себе сведения о соответствии переменных с идентификаторами. Идентификатором выступает имя переменной или «операции». Переменная – ссылка на объект. Может являться значением примитивного характера.</p>
<p>В лексическом окружении функции содержатся некие составляющие:</p>
<ul><li>запись окружения – пространство, в котором хранятся объявления «манипуляций» и переменных;</li><li>ссылка на внешнее окружение – своеобразная ссылка, которая позволяет обращаться к родительскому лексическому окружению.</li></ul>
<p>Именно ссылки «внешнего типа» выступают в качестве основополагающей для полноценного понимания замыканий.</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="458" height="165" src="https://otus.ru/journal/wp-content/uploads/2022/02/7.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2785" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/7.jpg 458w, https://otus.ru/journal/wp-content/uploads/2022/02/7-300x108.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/7-150x54.jpg 150w" sizes="(max-width: 458px) 100vw, 458px" /></figure>
<p>Выше представлен элемент кода, который описывает лексическое окружение.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9D%D0%B0_%D1%87%D1%82%D0%BE_%D1%81%D1%82%D0%BE%D0%B8%D1%82_%D0%BF%D0%BE%D0%B3%D0%BB%D1%8F%D0%B4%D0%B5%D1%82%D1%8C"></span>На что стоит поглядеть<span class="ez-toc-section-end"></span></h3>
<p>Вот код, который поможет лучше освоить «лексику»:</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="486" height="165" src="https://otus.ru/journal/wp-content/uploads/2022/02/8.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2786" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/8.jpg 486w, https://otus.ru/journal/wp-content/uploads/2022/02/8-300x102.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/8-150x51.jpg 150w" sizes="(max-width: 486px) 100vw, 486px" /></figure>
<p>Здесь происходит следующее:</p>
<ul type="1"><li>Движок Джавы будет отвечать за создание глобального контекста выполнения для обработки глобального кода.</li><li>После этого он создает новое лексическое окружения для того, чтобы хранить переменные и «операции», объявленные в глобальной области видимости.</li><li>Результатом окажется лексическое окружение: </li></ul>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="351" height="170" src="https://otus.ru/journal/wp-content/uploads/2022/02/9.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2787" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/9.jpg 351w, https://otus.ru/journal/wp-content/uploads/2022/02/9-300x145.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/9-150x73.jpg 150w" sizes="(max-width: 351px) 100vw, 351px" /></figure>
<ul type="1"><li>Ссылка на внешнее окружение (outer) стоит в значении null. Связано это с тем, что у глобальной «области видимости» отсутствует «лексика».</li><li>В процессе создания context для first() возникнет и «лексика» для хранения переменных объявленных в пределе оной и образованных при непосредственном выполнении.</li><li>Итог получится таким: </li></ul>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="370" height="152" src="https://otus.ru/journal/wp-content/uploads/2022/02/10.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2788" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/10.jpg 370w, https://otus.ru/journal/wp-content/uploads/2022/02/10-300x123.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/10-150x62.jpg 150w" sizes="(max-width: 370px) 100vw, 370px" /></figure>
<ul type="1"><li>Ссылка на внешнюю «лексику» устанавливается в значении <globalLexicalEnvironment>. Связано это с тем, что исходный код «операции» расположен в «глобальном пространстве».</li></ul>
<p>Стоит обратить внимание на то, что при завершении работы функции контекст будет извлекаться из стеков вызовов. Лексическое окружение может удаляться из памяти или оставаться в ней далее. Все зависит от существования ссылки на соответствующую «лексику» в виде ссылок на внешнее лексическое окружение в других рассматриваемых областях.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%92%D0%BD%D0%B5%D1%88%D0%BD%D0%B8%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5"></span>Внешние переменные<span class="ez-toc-section-end"></span></h2>
<p>Локальные переменные – не единственные, к которым можно обратиться из функции. Дополнительно предусматривается вызов внешних «хранилищ»:</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="303" height="119" src="https://otus.ru/journal/wp-content/uploads/2022/02/11.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2789" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/11.jpg 303w, https://otus.ru/journal/wp-content/uploads/2022/02/11-300x118.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/11-150x59.jpg 150w" sizes="(max-width: 303px) 100vw, 303px" /></figure>
<p>Интерпретатор при доступе к переменной будет в первую очередь пытаться обнаружить переменную в текущем LexicalEnvironment. Лишь после этого, при условии отсутствии оной – во внешнем объекте «хранилищ». В приведенном примере таковым выступает windows.</p>
<p>Подобное явление становится доступным из-за того, что ссылка на внешний объект переменных будет храниться в специальном свойстве функции внутреннего характера. А именно – в [[Scope]]. Оно не имеет прямого доступа, но это не значит, что программер должен обходить стороной оную. Знать принципы работы «Скоп» важно при программировании на JS.</p>
<p>Интерпретатор при создании «операции» создает для этой функции скрытое свойство [[Scope]]. Оно будет ссылаться на лексическое окружение, в котором оная создавалась.</p>
<p>Пример выше предусматривает такие явления:</p>
<ul type="1"><li>Упомянутый ранее окружением выступает window, что приводит к образованию свойства: </li></ul>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="234" height="38" src="https://otus.ru/journal/wp-content/uploads/2022/02/12.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2790" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/12.jpg 234w, https://otus.ru/journal/wp-content/uploads/2022/02/12-150x24.jpg 150w" sizes="(max-width: 234px) 100vw, 234px" /></figure>
<ul type="1"><li>Оное будет неизменным. Следует за «операцией», привязывая ее к своему месту рождения.</li><li>После запуска ее объект переменных LocalEnvironment получит ссылку на внешнюю «лексику» со значением из «Скоп».</li><li>Когда переменная не будет обнаружена в «манипуляции», произойдет ее поиск во внешней среде.</li></ul>
<p>Вывод к внешней переменной происходит за счет alert (username) за счет описанных принципов. В коде все это имеет интерпретацию поиска во внешней области видимости, за пределами функции.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%92%D0%B0%D0%B6%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D1%8B_%D0%B8_%D0%B2%D0%BD%D0%B5%D1%88%D0%BD%D0%B8%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5"></span>Важные выводы и внешние переменные<span class="ez-toc-section-end"></span></h3>
<p>В результате изученной информации можно сделать следующие заключения:</p>
<ol type="1"><li>Каждая «операция» будет при создании получать ссылку [[Scope]] на объект с переменными, в контексте которого она появилась.</li><li>После запуска создается новый объект с «хранилищами» LexicalEnvironment. Он получит ссылку на внешний объект переменных из [[Scope]].</li><li>Во время поиска переменных оный произойдет сначала внутри текущего объекта переменных, лишь после – по соответствующей ссылке.</li></ol>
<p>На первых порах подобная информация может показаться сложной. Но она позволяет разобраться в более важных для программиста вещах.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8_%E2%80%93_%D0%BA%D1%80%D0%B0%D1%82%D0%BA%D0%BE_%D0%BE_%D1%81%D0%B0%D0%BC%D0%BE%D0%BC_%D0%B2%D0%B0%D0%B6%D0%BD%D0%BE%D0%BC"></span>Функции – кратко о самом важном<span class="ez-toc-section-end"></span></h2>
<p>Замыкания в JS напрямую связаны с функциями. В них объявляются не только локальные переменные, но и другие «операции». А значит, целесообразно говорить о вложенности. Такой прием позволяет намного проще реализовывать некоторые программные коды.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%92%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8_%E2%80%93_%D0%BA%D0%B0%D0%BA_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D1%8F%D1%82%D1%8C"></span>Вложенные функции – как применять<span class="ez-toc-section-end"></span></h3>
<p>Вот пример кода:</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="744" height="265" src="https://otus.ru/journal/wp-content/uploads/2022/02/13.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2791" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/13.jpg 744w, https://otus.ru/journal/wp-content/uploads/2022/02/13-300x107.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/13-150x53.jpg 150w" sizes="(max-width: 744px) 100vw, 744px" /></figure>
<p>Он поможет разобраться с эффективным применением вложенных функций при замыканиях. Он предусматривает такие моменты:</p>
<ul type="1"><li>getFullName() – вспомогательная «операция».</li><li>Вложенные «манипуляции» получают [[Scope]] вместе с глобальными: </li></ul>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="607" height="47" src="https://otus.ru/journal/wp-content/uploads/2022/02/14.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2792" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/14.jpg 607w, https://otus.ru/journal/wp-content/uploads/2022/02/14-300x23.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/14-150x12.jpg 150w" sizes="(max-width: 607px) 100vw, 607px" /></figure>
<ul type="1"><li>Соответствующий прием обеспечит получение getFullName() снаружи lastName и firstName.</li></ul>
<p>Стоит обратить внимание на то, что при отсутствии рассматриваемой переменной во внешнем объекте, она будет искаться в «более внешнем» через [[Scope]] внешней «операции».</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="441" height="262" src="https://otus.ru/journal/wp-content/uploads/2022/02/15.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2793" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/15.jpg 441w, https://otus.ru/journal/wp-content/uploads/2022/02/15-300x178.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/15-150x89.jpg 150w" sizes="(max-width: 441px) 100vw, 441px" /></figure>
<p>Указанная ранее информация ведет к тому, что последний пример кода (выше) будет успешно работать.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%82_%E2%80%93_return_function"></span>Возврат – return function<span class="ez-toc-section-end"></span></h3>
<p>Но есть и более сложные ситуации. Пример – внутри одной «операции» будет создана другая, после чего система выведет оную в виде итогового результата. Такая манипуляция рассматривается при создании интерфейсов как «обычная». В виде «операции» может выступать обработчик действий клиента.</p>
<p>Рассматриваемый случай предусматривает счетчик-«манипуляцию», которая будет считывать собственные вызовы. Он возвращает текущее количество оных.</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="683" height="387" src="https://otus.ru/journal/wp-content/uploads/2022/02/16.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2794" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/16.jpg 683w, https://otus.ru/journal/wp-content/uploads/2022/02/16-300x170.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/16-150x85.jpg 150w" sizes="(max-width: 683px) 100vw, 683px" /></figure>
<p>Выше makeCounter будет создавать счетчик. Результат – два независимых «элемента» — counter и counter2. Каждый из них незаметно отвечает за сохранение количество вызовов в переменной внешнего типа currentCount. Ей обладает каждый счетчик.</p>
<h4 class="wp-block-heading"><span class="ez-toc-section" id="%D0%A7%D1%82%D0%BE_%D0%B7%D0%B4%D0%B5%D1%81%D1%8C_%D0%BF%D1%80%D0%BE%D0%B8%D1%81%D1%85%D0%BE%D0%B4%D0%B8%D1%82"></span>Что здесь происходит<span class="ez-toc-section-end"></span></h4>
<p>Если рассмотреть кодификацию подробно, будет происходить следующее:</p>
<ul type="1"><li>В строчке (*) запустится makeCounter, создастся LexicalEnvironment для переменных нынешнего вызова. У «операции» лишь одна переменная под названием var currentCount. Она выступит свойством соответствующего объекта. Сначала инициализируется в undefined, после обработки ей будет присвоено значение 1.</li></ul>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="579" height="282" src="https://otus.ru/journal/wp-content/uploads/2022/02/17.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2795" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/17.jpg 579w, https://otus.ru/journal/wp-content/uploads/2022/02/17-300x146.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/17-150x73.jpg 150w" sizes="(max-width: 579px) 100vw, 579px" /></figure>
<ul type="1"><li>Когда будет обрабатываться makeCounter, произойдет создание «операции» в строчке (**), что приведет к присваиванию внутреннего свойства [[Scope]]. Она получит ссылку на нынешнее LexicalEnvironment.</li><li>Вызов «МейкКантер» завершается. «Манипуляция» (**) будет возвращена и сохранена во внешней переменной counter (*).</li><li>В counter запишется «операция»: </li></ul>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="436" height="79" src="https://otus.ru/journal/wp-content/uploads/2022/02/18.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2796" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/18.jpg 436w, https://otus.ru/journal/wp-content/uploads/2022/02/18-300x54.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/18-150x27.jpg 150w" sizes="(max-width: 436px) 100vw, 436px" /></figure>
<ul type="1"><li>Counter, возвращенная из «МейкКантер» будет помнить об окружении, в котором возникла. Это происходит за счет «Скоп».</li><li>При вызове counter неизвестно, что произойдет, так как она содержит всего одну строку – с return. Собственные объект переменных (LE) окажется пустым.</li><li>За счет свойства [[Scope]] указывается внешнее окружение. Для увеличения и возврата currentCount интерпретатор будет искать в нынешнем объекте переменных LE. Оные не обнаружатся.</li><li>Осуществляется переход на внешний объект, где «предмет розыска» будет обнаружен, изменен и возвращен: </li></ul>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="529" height="282" src="https://otus.ru/journal/wp-content/uploads/2022/02/19.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2797" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/19.jpg 529w, https://otus.ru/journal/wp-content/uploads/2022/02/19-300x160.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/19-150x80.jpg 150w" sizes="(max-width: 529px) 100vw, 529px" /></figure>
<p>Переменные во внешних областях видимости удается не только считывать, но и корректировать.</p>
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="469" height="199" src="https://otus.ru/journal/wp-content/uploads/2022/02/20.jpg" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2798" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/20.jpg 469w, https://otus.ru/journal/wp-content/uploads/2022/02/20-300x127.jpg 300w, https://otus.ru/journal/wp-content/uploads/2022/02/20-150x64.jpg 150w" sizes="(max-width: 469px) 100vw, 469px" /></figure>
<p>Приведенный пример в console продемонстрировал независимость взаимного характера имеющихся счетчиков. Это из-за того, что при активации makeCounter будет создаваться собственный объект переменных LE с «личными» свойствами currentCount. Именно на него очередной счетчик будет получать ссылку [[Scope]].</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9A%D0%B0%D0%BA_%D0%B1%D1%8B%D1%81%D1%82%D1%80%D0%BE_%D0%BE%D1%81%D0%B2%D0%BE%D0%B8%D1%82%D1%8C_%D1%82%D0%B5%D0%BC%D1%83"></span>Как быстро освоить тему<span class="ez-toc-section-end"></span></h2>
<p>Изучая замыкание, можно легко запутаться. Это приводит к тому, что разобраться с выбранным направлением оказывается весьма проблематично. Но выход есть всегда – это дистанционные тематические курсы.</p>
<p>Срок обучения – от нескольких месяцев до года. Предложения для начинающих и опытных разработчиков. Гарантирована практика, а также контакты с опытными разработчиками. Можно в кратчайшие сроки выучить несколько языков программирования и углубиться в них. В конце обучения выдается электронный сертификат, подтверждающий знания.</p>
<figure class="wp-block-image size-large"><a href="https://otus.ru/lessons/specializacija-fullstack-dev/?utm_source=oj&utm_medium=affilate&utm_campaign=spec_js" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer"><img loading="lazy" decoding="async" width="970" height="70" src="https://otus.ru/journal/wp-content/uploads/2022/02/JS-FullstackSpec_Headline_970x70-16.png" alt="Замыкания в JavaScript: как не наделать ошибок" class="wp-image-2777" srcset="https://otus.ru/journal/wp-content/uploads/2022/02/JS-FullstackSpec_Headline_970x70-16.png 970w, https://otus.ru/journal/wp-content/uploads/2022/02/JS-FullstackSpec_Headline_970x70-16-300x22.png 300w, https://otus.ru/journal/wp-content/uploads/2022/02/JS-FullstackSpec_Headline_970x70-16-150x11.png 150w, https://otus.ru/journal/wp-content/uploads/2022/02/JS-FullstackSpec_Headline_970x70-16-768x55.png 768w" sizes="(max-width: 970px) 100vw, 970px" /></a></figure>
</div><!-- .post-content -->
<div class="the-post-foot cf">
<div class="tag-share cf">
<div class="post-tags"><a href="https://otus.ru/journal/tag/javascript/" rel="tag" data-wpel-link="internal">JavaScript</a></div>
<div class="post-share">
<div class="post-share-icons cf">
<span class="counters">
</span>
<a href="https://www.facebook.com/sharer.php?u=https%3A%2F%2Fotus.ru%2Fjournal%2Fzamykaniya-v-javascript-kak-ne-nadelat-oshibok%2F" class="link facebook wpel-icon-right" target="_blank" title="Share on Facebook" data-wpel-link="external" rel="nofollow external noopener noreferrer"><i class="fa fa-facebook"></i><span class="wpel-icon wpel-image wpel-icon-6"></span></a>
<a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fotus.ru%2Fjournal%2Fzamykaniya-v-javascript-kak-ne-nadelat-oshibok%2F&text=%D0%97%D0%B0%D0%BC%D1%8B%D0%BA%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%B2%20JavaScript%3A%20%D0%BA%D0%B0%D0%BA%20%D0%BD%D0%B5%20%D0%BD%D0%B0%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C%20%D0%BE%D1%88%D0%B8%D0%B1%D0%BE%D0%BA" class="link twitter wpel-icon-right" target="_blank" title="Share on Twitter" data-wpel-link="external" rel="nofollow external noopener noreferrer"><i class="fa fa-twitter"></i><span class="wpel-icon wpel-image wpel-icon-6"></span></a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fotus.ru%2Fjournal%2Fzamykaniya-v-javascript-kak-ne-nadelat-oshibok%2F" class="link linkedin wpel-icon-right" target="_blank" title="LinkedIn" data-wpel-link="external" rel="nofollow external noopener noreferrer"><i class="fa fa-linkedin"></i><span class="wpel-icon wpel-image wpel-icon-6"></span></a>
<a href="https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fotus.ru%2Fjournal%2Fzamykaniya-v-javascript-kak-ne-nadelat-oshibok%2F&media=https%3A%2F%2Fotus.ru%2Fjournal%2Fwp-content%2Fuploads%2F2022%2F02%2Foj-1080x720-1-1.png&description=%D0%97%D0%B0%D0%BC%D1%8B%D0%BA%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%B2%20JavaScript%3A%20%D0%BA%D0%B0%D0%BA%20%D0%BD%D0%B5%20%D0%BD%D0%B0%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C%20%D0%BE%D1%88%D0%B8%D0%B1%D0%BE%D0%BA" class="link pinterest wpel-icon-right" target="_blank" title="Pinterest" data-wpel-link="external" rel="nofollow external noopener noreferrer"><i class="fa fa-pinterest-p"></i><span class="wpel-icon wpel-image wpel-icon-6"></span></a>
</div>
</div>
</div>
</div>
<div class="post-nav">
<div class="post previous cf">
<a href="https://otus.ru/journal/tipizaciya-v-programmirovanii/" title="Prev Post" class="nav-icon" data-wpel-link="internal">
<i class="fa fa-angle-left"></i>
</a>
<span class="content">
<a href="https://otus.ru/journal/tipizaciya-v-programmirovanii/" class="image-link" rel="previous" data-wpel-link="internal">
<img width="150" height="100" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20150%20100%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="attachment-thumbnail size-thumbnail lazyload wp-post-image" alt="Типизация в программировании" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-150x100.png 150w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-300x200.png 300w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-1024x683.png 1024w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-768x512.png 768w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-270x180.png 270w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-770x515.png 770w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-370x245.png 370w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1.png 1080w" data-src="https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-1-150x100.png" data-sizes="(max-width: 150px) 100vw, 150px" title="Типизация в программировании" /> </a>
<div class="post-meta">
<span class="label">Prev Post</span>
<div class="post-meta post-meta-b">
<h2 class="post-title">
<a href="https://otus.ru/journal/tipizaciya-v-programmirovanii/" data-wpel-link="internal">Типизация в программировании</a>
</h2>
<div class="below">
<a href="https://otus.ru/journal/tipizaciya-v-programmirovanii/" class="meta-item date-link" data-wpel-link="internal"><time class="post-date" datetime="2022-02-03T17:08:09+00:00">3 февраля, 2022</time></a>
<span class="meta-sep"></span>
<span class="meta-item read-time">9 Mins Read</span>
</div>
</div> </div>
</span>
</div>
<div class="post next cf">
<a href="https://otus.ru/journal/java-script-i-potoki-poleznaya-informaciya-o-mnogopotochnosti/" title="Next Post" class="nav-icon" data-wpel-link="internal">
<i class="fa fa-angle-right"></i>
</a>
<span class="content">
<a href="https://otus.ru/journal/java-script-i-potoki-poleznaya-informaciya-o-mnogopotochnosti/" class="image-link" rel="next" data-wpel-link="internal">
<img width="150" height="100" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20150%20100%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="attachment-thumbnail size-thumbnail lazyload wp-post-image" alt="Java Script и потоки: полезная информация о многопоточности" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2-150x100.png 150w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2-300x200.png 300w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2-1024x683.png 1024w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2-768x512.png 768w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2-270x180.png 270w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2-770x515.png 770w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2-370x245.png 370w, https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2.png 1080w" data-src="https://otus.ru/journal/wp-content/uploads/2022/02/oj-1080x720-2-150x100.png" data-sizes="(max-width: 150px) 100vw, 150px" title="Java Script и потоки: полезная информация о многопоточности" /> </a>
<div class="post-meta">
<span class="label">Next Post</span>
<div class="post-meta post-meta-b">
<h2 class="post-title">
<a href="https://otus.ru/journal/java-script-i-potoki-poleznaya-informaciya-o-mnogopotochnosti/" data-wpel-link="internal">Java Script и потоки: полезная информация о многопоточности</a>
</h2>
<div class="below">
<a href="https://otus.ru/journal/java-script-i-potoki-poleznaya-informaciya-o-mnogopotochnosti/" class="meta-item date-link" data-wpel-link="internal"><time class="post-date" datetime="2022-02-03T17:46:19+00:00">3 февраля, 2022</time></a>
<span class="meta-sep"></span>
<span class="meta-item read-time">9 Mins Read</span>
</div>
</div> </div>
</span>
</div>
</div>
<section class="related-posts grid-3">
<h4 class="section-head"><span class="title">Читать ещё</span></h4>
<div class="ts-row posts cf">
<article class="post col-4">
<a href="https://otus.ru/journal/uroven-gotovnosti-cto-k-2026/" title="Уровень готовности CTO к 2026" class="image-link" data-wpel-link="internal">
<img width="270" height="180" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20270%20180%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="image lazyload wp-post-image" alt="Уровень готовности CTO к 2026" title="Уровень готовности CTO к 2026" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-3-270x180.jpg 270w, https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-3-770x515.jpg 770w, https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-3-370x245.jpg 370w" data-src="https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-3-270x180.jpg" data-sizes="(max-width: 270px) 100vw, 270px" /> </a>
<div class="content">
<h3 class="post-title"><a href="https://otus.ru/journal/uroven-gotovnosti-cto-k-2026/" class="post-link" data-wpel-link="internal">Уровень готовности CTO к 2026</a></h3>
<div class="post-meta">
<time class="post-date" datetime="2025-11-16T19:50:59+00:00">16 ноября, 2025</time>
</div>
</div>
</article >
<article class="post col-4">
<a href="https://otus.ru/journal/novye-uroki-noyabrya-tolko-top-temy-po-programmirovaniju/" title="Новые уроки ноября: только топ-темы по программированию" class="image-link" data-wpel-link="internal">
<img width="270" height="180" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20270%20180%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="image lazyload wp-post-image" alt="Новые уроки ноября: только топ-темы по программированию" title="Новые уроки ноября: только топ-темы по программированию" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-2-270x180.jpg 270w, https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-2-770x515.jpg 770w, https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-2-370x245.jpg 370w" data-src="https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-2-270x180.jpg" data-sizes="(max-width: 270px) 100vw, 270px" /> </a>
<div class="content">
<h3 class="post-title"><a href="https://otus.ru/journal/novye-uroki-noyabrya-tolko-top-temy-po-programmirovaniju/" class="post-link" data-wpel-link="internal">Новые уроки ноября: только топ-темы по программированию</a></h3>
<div class="post-meta">
<time class="post-date" datetime="2025-11-09T23:24:11+00:00">9 ноября, 2025</time>
</div>
</div>
</article >
<article class="post col-4">
<a href="https://otus.ru/journal/schjot-idjot-na-chasy/" title="Счёт идёт на часы" class="image-link" data-wpel-link="internal">
<img width="270" height="180" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20270%20180%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="image lazyload wp-post-image" alt="Счёт идёт на часы" title="Счёт идёт на часы" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2025/10/oj-1080x720-kopiya-7-270x180.png 270w, https://otus.ru/journal/wp-content/uploads/2025/10/oj-1080x720-kopiya-7-770x515.png 770w, https://otus.ru/journal/wp-content/uploads/2025/10/oj-1080x720-kopiya-7-370x245.png 370w" data-src="https://otus.ru/journal/wp-content/uploads/2025/10/oj-1080x720-kopiya-7-270x180.png" data-sizes="(max-width: 270px) 100vw, 270px" /> </a>
<div class="content">
<h3 class="post-title"><a href="https://otus.ru/journal/schjot-idjot-na-chasy/" class="post-link" data-wpel-link="internal">Счёт идёт на часы</a></h3>
<div class="post-meta">
<time class="post-date" datetime="2025-10-30T15:04:59+00:00">30 октября, 2025</time>
</div>
</div>
</article >
</div>
</section>
</article> <!-- .the-post -->
</div>
<aside class="col-4 sidebar">
<div class="inner">
<ul>
<li id="search-2" class="widget widget_search"><h5 class="widget-title"><span>Поиск по блогу</span></h5>
<form method="get" class="search-form" action="https://otus.ru/journal/">
<label>
<span class="screen-reader-text">Search for:</span>
<input type="search" class="search-field" placeholder="Введите запрос и нажмите Enter" value="" name="s" title="Search for:" />
</label>
<button type="submit" class="search-submit"><i class="fa fa-search"></i></button>
</form>
</li>
<li id="tag_cloud-5" class="widget widget_tag_cloud"><h5 class="widget-title"><span>Метки</span></h5><div class="tagcloud"><a href="https://otus.ru/journal/tag/android-2/" class="tag-cloud-link tag-link-74 tag-link-position-1" style="font-size: 12.472222222222pt;" aria-label="Android (34 элемента)" data-wpel-link="internal">Android</a>
<a href="https://otus.ru/journal/tag/c-3/" class="tag-cloud-link tag-link-91 tag-link-position-2" style="font-size: 10.916666666667pt;" aria-label="C (23 элемента)" data-wpel-link="internal">C</a>
<a href="https://otus.ru/journal/tag/c-2/" class="tag-cloud-link tag-link-81 tag-link-position-3" style="font-size: 12.666666666667pt;" aria-label="C# (35 элементов)" data-wpel-link="internal">C#</a>
<a href="https://otus.ru/journal/tag/c/" class="tag-cloud-link tag-link-20 tag-link-position-4" style="font-size: 12.472222222222pt;" aria-label="c++ (34 элемента)" data-wpel-link="internal">c++</a>
<a href="https://otus.ru/journal/tag/computer-science/" class="tag-cloud-link tag-link-209 tag-link-position-5" style="font-size: 15.972222222222pt;" aria-label="computer science (78 элементов)" data-wpel-link="internal">computer science</a>
<a href="https://otus.ru/journal/tag/css/" class="tag-cloud-link tag-link-288 tag-link-position-6" style="font-size: 8.6805555555556pt;" aria-label="CSS (13 элементов)" data-wpel-link="internal">CSS</a>
<a href="https://otus.ru/journal/tag/data-science/" class="tag-cloud-link tag-link-151 tag-link-position-7" style="font-size: 8pt;" aria-label="Data Science (11 элементов)" data-wpel-link="internal">Data Science</a>
<a href="https://otus.ru/journal/tag/devops/" class="tag-cloud-link tag-link-98 tag-link-position-8" style="font-size: 10.138888888889pt;" aria-label="devops (19 элементов)" data-wpel-link="internal">devops</a>
<a href="https://otus.ru/journal/tag/docker/" class="tag-cloud-link tag-link-143 tag-link-position-9" style="font-size: 8.2916666666667pt;" aria-label="Docker (12 элементов)" data-wpel-link="internal">Docker</a>
<a href="https://otus.ru/journal/tag/gamedev/" class="tag-cloud-link tag-link-25 tag-link-position-10" style="font-size: 11.694444444444pt;" aria-label="gamedev (28 элементов)" data-wpel-link="internal">gamedev</a>
<a href="https://otus.ru/journal/tag/hr/" class="tag-cloud-link tag-link-103 tag-link-position-11" style="font-size: 8pt;" aria-label="hr (11 элементов)" data-wpel-link="internal">hr</a>
<a href="https://otus.ru/journal/tag/html/" class="tag-cloud-link tag-link-217 tag-link-position-12" style="font-size: 11.208333333333pt;" aria-label="HTML (25 элементов)" data-wpel-link="internal">HTML</a>
<a href="https://otus.ru/journal/tag/ios/" class="tag-cloud-link tag-link-101 tag-link-position-13" style="font-size: 8.9722222222222pt;" aria-label="iOS (14 элементов)" data-wpel-link="internal">iOS</a>
<a href="https://otus.ru/journal/tag/it/" class="tag-cloud-link tag-link-50 tag-link-position-14" style="font-size: 10.527777777778pt;" aria-label="IT (21 элемент)" data-wpel-link="internal">IT</a>
<a href="https://otus.ru/journal/tag/java/" class="tag-cloud-link tag-link-75 tag-link-position-15" style="font-size: 15.680555555556pt;" aria-label="Java (73 элемента)" data-wpel-link="internal">Java</a>
<a href="https://otus.ru/journal/tag/javascript/" class="tag-cloud-link tag-link-83 tag-link-position-16" style="font-size: 14.319444444444pt;" aria-label="JavaScript (53 элемента)" data-wpel-link="internal">JavaScript</a>
<a href="https://otus.ru/journal/tag/linux/" class="tag-cloud-link tag-link-141 tag-link-position-17" style="font-size: 11.888888888889pt;" aria-label="Linux (29 элементов)" data-wpel-link="internal">Linux</a>
<a href="https://otus.ru/journal/tag/machine-learning/" class="tag-cloud-link tag-link-167 tag-link-position-18" style="font-size: 8.6805555555556pt;" aria-label="Machine Learning (13 элементов)" data-wpel-link="internal">Machine Learning</a>
<a href="https://otus.ru/journal/tag/otus-book/" class="tag-cloud-link tag-link-261 tag-link-position-19" style="font-size: 9.9444444444444pt;" aria-label="otus book (18 элементов)" data-wpel-link="internal">otus book</a>
<a href="https://otus.ru/journal/tag/php/" class="tag-cloud-link tag-link-45 tag-link-position-20" style="font-size: 10.527777777778pt;" aria-label="PHP (21 элемент)" data-wpel-link="internal">PHP</a>
<a href="https://otus.ru/journal/tag/python/" class="tag-cloud-link tag-link-27 tag-link-position-21" style="font-size: 16.944444444444pt;" aria-label="Python (99 элементов)" data-wpel-link="internal">Python</a>
<a href="https://otus.ru/journal/tag/qa/" class="tag-cloud-link tag-link-155 tag-link-position-22" style="font-size: 11.402777777778pt;" aria-label="qa (26 элементов)" data-wpel-link="internal">qa</a>
<a href="https://otus.ru/journal/tag/sql/" class="tag-cloud-link tag-link-38 tag-link-position-23" style="font-size: 12.861111111111pt;" aria-label="SQL (37 элементов)" data-wpel-link="internal">SQL</a>
<a href="https://otus.ru/journal/tag/team-lead/" class="tag-cloud-link tag-link-364 tag-link-position-24" style="font-size: 9.9444444444444pt;" aria-label="team lead (18 элементов)" data-wpel-link="internal">team lead</a>
<a href="https://otus.ru/journal/tag/unity/" class="tag-cloud-link tag-link-24 tag-link-position-25" style="font-size: 8pt;" aria-label="unity (11 элементов)" data-wpel-link="internal">unity</a>
<a href="https://otus.ru/journal/tag/algoritmy/" class="tag-cloud-link tag-link-30 tag-link-position-26" style="font-size: 9.9444444444444pt;" aria-label="Алгоритмы (18 элементов)" data-wpel-link="internal">Алгоритмы</a>
<a href="https://otus.ru/journal/tag/bazy-dannyh/" class="tag-cloud-link tag-link-40 tag-link-position-27" style="font-size: 10.138888888889pt;" aria-label="Базы данных (19 элементов)" data-wpel-link="internal">Базы данных</a>
<a href="https://otus.ru/journal/tag/matematika/" class="tag-cloud-link tag-link-44 tag-link-position-28" style="font-size: 10.916666666667pt;" aria-label="Математика (23 элемента)" data-wpel-link="internal">Математика</a>
<a href="https://otus.ru/journal/tag/arhitektura-po/" class="tag-cloud-link tag-link-10 tag-link-position-29" style="font-size: 9.4583333333333pt;" aria-label="архитектура ПО (16 элементов)" data-wpel-link="internal">архитектура ПО</a>
<a href="https://otus.ru/journal/tag/bazy-dannyh-2/" class="tag-cloud-link tag-link-251 tag-link-position-30" style="font-size: 10.138888888889pt;" aria-label="базы данных (19 элементов)" data-wpel-link="internal">базы данных</a>
<a href="https://otus.ru/journal/tag/vebinar/" class="tag-cloud-link tag-link-201 tag-link-position-31" style="font-size: 13.930555555556pt;" aria-label="вебинар (48 элементов)" data-wpel-link="internal">вебинар</a>
<a href="https://otus.ru/journal/tag/dajdzhest/" class="tag-cloud-link tag-link-308 tag-link-position-32" style="font-size: 10.722222222222pt;" aria-label="дайджест (22 элемента)" data-wpel-link="internal">дайджест</a>
<a href="https://otus.ru/journal/tag/zapis-vebinara/" class="tag-cloud-link tag-link-226 tag-link-position-33" style="font-size: 14.902777777778pt;" aria-label="запись вебинара (61 элемент)" data-wpel-link="internal">запись вебинара</a>
<a href="https://otus.ru/journal/tag/zapis-uroka/" class="tag-cloud-link tag-link-272 tag-link-position-34" style="font-size: 16.069444444444pt;" aria-label="запись урока (80 элементов)" data-wpel-link="internal">запись урока</a>
<a href="https://otus.ru/journal/tag/informacionnaya-bezopasnost/" class="tag-cloud-link tag-link-232 tag-link-position-35" style="font-size: 10.138888888889pt;" aria-label="информационная безопасность (19 элементов)" data-wpel-link="internal">информационная безопасность</a>
<a href="https://otus.ru/journal/tag/karera-v-it/" class="tag-cloud-link tag-link-292 tag-link-position-36" style="font-size: 9.9444444444444pt;" aria-label="карьера в IT (18 элементов)" data-wpel-link="internal">карьера в IT</a>
<a href="https://otus.ru/journal/tag/podborka/" class="tag-cloud-link tag-link-7 tag-link-position-37" style="font-size: 12.666666666667pt;" aria-label="подборка (35 элементов)" data-wpel-link="internal">подборка</a>
<a href="https://otus.ru/journal/tag/podborka-statej/" class="tag-cloud-link tag-link-219 tag-link-position-38" style="font-size: 15.777777777778pt;" aria-label="подборка статей (75 элементов)" data-wpel-link="internal">подборка статей</a>
<a href="https://otus.ru/journal/tag/programmirovanie/" class="tag-cloud-link tag-link-65 tag-link-position-39" style="font-size: 22pt;" aria-label="программирование (332 элемента)" data-wpel-link="internal">программирование</a>
<a href="https://otus.ru/journal/tag/proekt/" class="tag-cloud-link tag-link-321 tag-link-position-40" style="font-size: 11.888888888889pt;" aria-label="проект (29 элементов)" data-wpel-link="internal">проект</a>
<a href="https://otus.ru/journal/tag/proektnaya-rabota/" class="tag-cloud-link tag-link-310 tag-link-position-41" style="font-size: 11.597222222222pt;" aria-label="проектная работа (27 элементов)" data-wpel-link="internal">проектная работа</a>
<a href="https://otus.ru/journal/tag/seti/" class="tag-cloud-link tag-link-181 tag-link-position-42" style="font-size: 12.958333333333pt;" aria-label="сети (38 элементов)" data-wpel-link="internal">сети</a>
<a href="https://otus.ru/journal/tag/testirovanie/" class="tag-cloud-link tag-link-69 tag-link-position-43" style="font-size: 13.930555555556pt;" aria-label="тестирование (48 элементов)" data-wpel-link="internal">тестирование</a>
<a href="https://otus.ru/journal/tag/upravlenie-komandoj/" class="tag-cloud-link tag-link-63 tag-link-position-44" style="font-size: 11.694444444444pt;" aria-label="управление командой (28 элементов)" data-wpel-link="internal">управление командой</a>
<a href="https://otus.ru/journal/tag/habr-2/" class="tag-cloud-link tag-link-203 tag-link-position-45" style="font-size: 13.930555555556pt;" aria-label="хабр (48 элементов)" data-wpel-link="internal">хабр</a></div>
</li>
</ul>
</div>
</aside>
</div> <!-- .ts-row -->
</div> <!-- .main -->
<footer class="main-footer dark bold">
<section class="lower-footer cf">
<div class="wrap">
<div class="links">
<div class="menu-menju-navykov-container"><ul id="menu-menju-navykov-1" class="menu"><li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10413"><a href="https://otus.ru/categories/programming/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Программирование<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10414"><a href="https://otus.ru/categories/architecture/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Архитектура<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10415"><a href="https://otus.ru/categories/operations/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Инфраструктура<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10416"><a href="https://otus.ru/categories/information-security-courses/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Безопасность<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10417"><a href="https://otus.ru/categories/data-science/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Data Science<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10418"><a href="https://otus.ru/categories/gamedev/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">GameDev<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10419"><a href="https://otus.ru/categories/marketing-business/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Управление<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10420"><a href="https://otus.ru/categories/analytics/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Аналитика и анализ<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10421"><a href="https://otus.ru/categories/testing/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Тестирование<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
</ul></div> </div>
<p class="copyright"> © 2015-2026 OTUS </p>
<div class="to-top">
<a href="#" class="back-to-top"><i class="fa fa-angle-up"></i> Top</a>
</div>
</div>
</section>
</footer>
</div> <!-- .main-wrap -->
<div class="mobile-menu-container off-canvas" id="mobile-menu">
<a href="#" class="close"><i class="fa fa-times"></i></a>
<div class="logo">
</div>
<ul class="mobile-menu"></ul>
</div>
<div class="search-modal-wrap">
<div class="search-modal-box" role="dialog" aria-modal="true">
<form method="get" class="search-form" action="https://otus.ru/journal/">
<input type="search" class="search-field" name="s" placeholder="Search..." value="" required />
<button type="submit" class="search-submit visuallyhidden">Submit</button>
<p class="message">
Type above and press <em>Enter</em> to search. Press <em>Esc</em> to cancel. </p>
</form>
</div>
</div>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/clearfy/components/comments-plus/assets/js/url-span.js" id="wbcr-comments-plus-url-span-js"></script>
<script type="text/javascript" id="ez-toc-scroll-scriptjs-js-extra">
/* <![CDATA[ */
var eztoc_smooth_local = {"scroll_offset":"30"};
/* ]]> */
</script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/assets/js/smooth_scroll.min.js" id="ez-toc-scroll-scriptjs-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/vendor/js-cookie/js.cookie.min.js" id="ez-toc-js-cookie-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/vendor/sticky-kit/jquery.sticky-kit.min.js" id="ez-toc-jquery-sticky-kit-js"></script>
<script type="text/javascript" id="ez-toc-js-js-extra">
/* <![CDATA[ */
var ezTOC = {"smooth_scroll":"1","visibility_hide_by_default":"","scroll_offset":"30","fallbackIcon":"<span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span>"};
/* ]]> */
</script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/assets/js/front.min.js" id="ez-toc-js-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/custom-script.js" id="custom-script-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/magnific-popup.js" id="magnific-popup-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/jquery.fitvids.js" id="jquery-fitvids-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/imagesloaded.min.js" id="imagesloaded-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/object-fit-images.js" id="object-fit-images-js"></script>
<script type="text/javascript" id="contentberg-theme-js-extra">
/* <![CDATA[ */
var Bunyad = {"custom_ajax_url":"\/journal\/zamykaniya-v-javascript-kak-ne-nadelat-oshibok\/"};
/* ]]> */
</script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/theme.js" id="contentberg-theme-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/theia-sticky-sidebar.js" id="theia-sticky-sidebar-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/jquery.slick.js" id="jquery-slick-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/jarallax.js" id="jarallax-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/masonry.min.js" id="masonry-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/jquery/jquery.masonry.min.js" id="jquery-masonry-js"></script>
</body>
</html>
<!-- Cache served by breeze CACHE - Last modified: Tue, 10 Mar 2026 15:10:06 GMT -->