Лексическое окружение
Начну серию постов, связанную с замыканиями, утечками памяти через замыкания, stale state и stale props в React. В Javascript есть три основные концепции, связанные с замыканиями:
🔹 Lexical environment
🔹 Environment record
🔹 Execution context
Сегодня поговорим о первой из них, а именно - о лексическом окружении.
🔶 Лексическое окружение - это структура, которая определяет, какие идентификаторы (т.е. переменные) доступны в данном фрагменте кода. Создается в момент вызова. Фрагментами кода, которые создают новое лексическое окружение, являются:
🔹 Js файлы. Когда мы запускаем код из js файла, создается глобальное лексическое окружение, и переменные из него будут доступны в любом месте в этом файле
🔹Функции. Вызов функции создает новое лексическое окружение для нее, повторный вызов создаст новое лексическое окружение
🔹Блок кода (то, что внутри
Каждое лексическое окружение имеет ссылку на внешнее лексическое окружение. Для глобального лексического окружения ссылка на внешнее будет равна null.
На картинке выше вы можете увидеть код и схематичное изображение его лексического окружения. Лексическое окружение foo содержит в себе идентификатор
#javascript #замыкание #lexical_environment
Начну серию постов, связанную с замыканиями, утечками памяти через замыкания, stale state и stale props в React. В Javascript есть три основные концепции, связанные с замыканиями:
🔹 Lexical environment
🔹 Environment record
🔹 Execution context
Сегодня поговорим о первой из них, а именно - о лексическом окружении.
🔶 Лексическое окружение - это структура, которая определяет, какие идентификаторы (т.е. переменные) доступны в данном фрагменте кода. Создается в момент вызова. Фрагментами кода, которые создают новое лексическое окружение, являются:
🔹 Js файлы. Когда мы запускаем код из js файла, создается глобальное лексическое окружение, и переменные из него будут доступны в любом месте в этом файле
🔹Функции. Вызов функции создает новое лексическое окружение для нее, повторный вызов создаст новое лексическое окружение
🔹Блок кода (то, что внутри
{}). Когда интерпретатор доходит до блока кода, он создает новое лексическое окружение, в котором могут находиться переменные, объявленные через let и const. Каждое лексическое окружение имеет ссылку на внешнее лексическое окружение. Для глобального лексического окружения ссылка на внешнее будет равна null.
На картинке выше вы можете увидеть код и схематичное изображение его лексического окружения. Лексическое окружение foo содержит в себе идентификатор
c и ссылку на внешнее лексическое окружение, которое является глобальным. Глобальное лексическое окружение содержит в себе два идентификатора, а его ссылка на внешнее лексическое окружение равна null.#javascript #замыкание #lexical_environment
👍11❤8
⚡️ Что такое замыкание и как оно приводит к утечкам памяти
В прошлый раз мы с вами говорили о лексическом окружении и причинах его создания, а сегодня поговорим о замыканиях. Термином “замыкание” в javascript обозначает функцию и ее лексическое окружение. Как вы помните, лексическое окружение в javascript содержит в себе ссылку на внешнее лексическое окружение - таким образом, все внешние лексические окружения для функции будут доступны ей через цепочку ссылок.
Что происходит с лексическим окружением функции после того, как она завершила свою работу? Довольно часто оно больше не нужно и уничтожается, однако бывает и иначе. Рассмотрим пример:
Функция
В данном случае
#замыкание #javascript
В прошлый раз мы с вами говорили о лексическом окружении и причинах его создания, а сегодня поговорим о замыканиях. Термином “замыкание” в javascript обозначает функцию и ее лексическое окружение. Как вы помните, лексическое окружение в javascript содержит в себе ссылку на внешнее лексическое окружение - таким образом, все внешние лексические окружения для функции будут доступны ей через цепочку ссылок.
Что происходит с лексическим окружением функции после того, как она завершила свою работу? Довольно часто оно больше не нужно и уничтожается, однако бывает и иначе. Рассмотрим пример:
function makeCounter() {
let count = 0;
const increment = () => count++;
return increment;
}
let counter = makeCounter();
counter();
counter();Функция
makeCounter завершила свою работу, однако лексическое окружение, которое она создала - с идентификатором count в нем - осталось в памяти. Почему так? Потому что лексическое окружение функции makeCounter - внешнее для лексического окружения функции increment, которая в нем создается. Когда мы вернули из makeCounter функцию increment, прицепом к ней мы вернули все ее лексическое окружение. Поскольку на это лексическое окружение ссылается increment (ниже counter - это две переменных указывают на одну область памяти), то лексическое окружение вместе с переменной count надежно зависло в памяти до тех пор, пока counter остается ссылочно доступен. В данном случае
makeCounter у нас “зависло” совсем маленькое лексическое окружение с переменной count - однако бывают и гораздо более серьезные утечки памяти, связанные с замыканиями. Такая ситуация происходит, если “зависшее” лексическое окружение занимает много места в памяти и/или ссылается на другие “тяжелые” лексические окружения. Вот здесь я писала об одной из таких утечек в Promise.race, а в следующий раз поговорим с вами о том, как “зависшее” лексическое окружение приводит к ситуациям, которые мы называем stale props и stale state.#замыкание #javascript
Telegram
Фронтенд кухня🥘
Promise.race
Всем привет, на связи Марго @devmargooo и сегодня я расскажу вам про Promise.race.🏎 Promise.race принимает в качестве аргумента массив промисов и возвращает результат того промиса, который завершится первым. Значит ли это, что после завершения…
Всем привет, на связи Марго @devmargooo и сегодня я расскажу вам про Promise.race.🏎 Promise.race принимает в качестве аргумента массив промисов и возвращает результат того промиса, который завершится первым. Значит ли это, что после завершения…
⚡11❤7👍3