Переменная в javascript. Нужна помощь в теории.

Хочу понять такую вещь.
Что из себя представляет переменная в js и самое главное — какой ее «жизненный» цикл.
Буду рад вашим размышлениям.

Итак. Есть html код внутри которого находится просто объявление и присвоение значения переменной js. Мы открыли эту страницу в браузере, код выполнился.
1) Почему после полного отображения страницы, выполнения всех скриптов, переменная все еще доступна? Почему мы можем в консоли браузера получить ее, изменить? Разве не должна она был быть убита, когда страница полностью загрузилась?
2) Раз переменная созданная в процессе выполнения кода в браузере все еще жива, когда страница загрузилась, то вопрос — а когда она будет удалена? В момент закрытия вкладки браузера? В момент закрытия браузера? Нигде не нашел в учебниках информации (хотя и не буду утверждать что сильно искал).
3) Да я знаю что в js есть сборщик мусора и я прочел как он работает — удаляет переменные на которые уже не ведут ссылки. Но в моем понимании это должно происходить в момент выполнения кода, разве нет? js интерпретируемый язык, интерпретатор встроенный в браузер читает его, выполняет и сборщик мусора чистит память, если на какую то переменную больше нет ссылок. Но если код выполнен, страница загрузилась, разве не должны все переменные быть очищены? Тогда в какой момент они будут удалены?

Если кто знает где почитать о js именно на таком глубоком уровне как работа с памятью, жизненный цикл переменных в браузере — буду благодарен.
Александр Мельник
11 октября 2020, 18:18
modx.pro
499
0

Комментарии: 31

Александр Мельник
11 октября 2020, 18:49
0
я пытался сам себе пояснить, что мол глобально объявленные переменные становятся свойствами объекта window, а этот объект живет столько сколько открыто окно.
Но нет.
«современный синтаксис» задания переменных не помещает их в свойства window.
<body>
    <h2>Objects</h2>
    <script>
        'use strict'
        const test1 = 1;
        let test2 = 2;
        var test3 = 3;

        const user = {
            name: 'alex',
            age: 40
        };
    </script>
</body>
Только test 3 заданная через устаревший var попала в window. Остальные переменные — нет. А значит почему они «живы» мне не ясно)
      Александр Мельник
      11 октября 2020, 23:37
      0
      спасибо Иван, но все эти статьи о разницах между const, var let а ведь мой вопрос был не о них.
      Я хочу понять как работает сборка мусора в javascript и какой жизненный цикл переменных в браузере, в какой момент очищается оперативная память, выделенная под определенную переменную и так далее.
        Артем
        12 октября 2020, 02:00
        +1
        Разве не должна она был быть убита, когда страница полностью загрузилась?
        Нет, это же не php, который born to die.

        а когда она будет удалена?
        Когда на нее не останется ссылок. Браузер тут вообще ни при чем, он предоставляет только интерпретатор JS.
        Почитай про WeakMap и WeakSet, там подробнее объясняется про сборку мусора и вот это все.
        Ну и там же есть ссылка на отдельную статью про сборку мусора.

        жизненный цикл переменных в браузере
        В браузере он ничем не отличается от того же Node.js, например. В обоих случаях JS не умирает так, как ты привык об этом думать из-за php.
          Александр Мельник
          12 октября 2020, 08:11
          0
          спасибо. действительно, я изучаю js сквозь призму знаний о php и это сбивает с толку. В моем понимании раз скрипт отработал, то зачем же все значения переменных остались лежать в оперативной памяти.
            Артем
            14 октября 2020, 20:49
            0
            я изучаю js сквозь призму знаний о php
            В этом и проблема: PHP и JS имеют абсолютно разную философию и цели, поэтому и работают по-разному.
            Задача PHP — обработать запрос, выплюнуть какой-нибудь ответ и помереть. Тот же Node.js единожды инициализируется и дальше обрабатывает сколько угодно запросов, продолжая хранить все ранее инциализированные переменные в оперативке.
            Соответственно, в Node.js нельзя просто сделать условный exit (die), чтобы быстренько помереть в рандомом месте приложения и выплюнуть ответ. Это может стать сюрпризом и вызвать сложности на первых порах, но в целом это помогает грамотнее проектировать приложение и уделять больше внимания его циклу жизни.
              Александр Мельник
              14 октября 2020, 21:00
              0
              да, я понимаю, поэтому и стараюсь «выбросить из головы» концепции php.
              два момента только:
              — в учебниках крайне мало уделяется внимания именно этому аспекту, поэтому и спрашиваю у более опытных.
              — плюс мне кажется что js в браузере и js на сервере это немного разные вещи. У них одинаковый синтаксис но разная идеология, нет? node js это прежде всего процесс в операционной системе, он регистрируется как сервис (по крайней мере в линуксе) и понятное дело — работает постоянно. js в браузере — это лишь код, которые обрабатывается встроенным в браузер интерпретатором. И мне сложно представить что он единожды инициализируется и дальше работает.
                Артем
                14 октября 2020, 21:28
                0
                в учебниках крайне мало уделяется внимания именно этому аспекту, поэтому и спрашиваю у более опытных
                А чему уделять внимание? Держи в голове, что JS работает иначе, а погружаться в детали и пытаться понять логику работы под капотом — лишнее для тебя сейчас, имхо. Тебе нужно учить именно сам JS — фишки ES6+, пытаться писать оптимальный и грамотный код, а не лезть в дебри. Эти знания тебе сейчас практически ничего не дадут. Да, нужно знать какую-то базу про Event Loop, но эти базовые знания можно получить из 1-2 статей.

                плюс мне кажется что js в браузере и js на сервере это немного разные вещи.
                Да, конечно, различия есть, но эти различия — особенности среды исполнения, а не какие-то «фишки языка». Язык работает одинаково как в хроме, так и в ноде, потому что там работает один и тот же интерпретатор v8.
                Опять же, тебе не нужно фокусироваться на этих различиях, если ты не пишешь серверную часть на ноде.

                js в браузере — это лишь код, которые обрабатывается встроенным в браузер интерпретатором. И мне сложно представить что он единожды инициализируется и дальше работает.
                Если так уж интересно, то по такому принципу работает консоль в браузере.
            Александр Мельник
            12 октября 2020, 08:29
            0
            До WeakMap я еще не дошел в этом учебнике, спасибо.
            Знаете что еще немного удивляет в js — это отсутствие официальной документации.
            Я ведь не ошибаюсь — ее нет? У php есть php.net документация на котором ведется разработчиками, у python есть python.org, но я не встречал официального сайта по js (ну и кстати по CSS тоже). Есть learn.javascript есть mozilla MDN (но mozilla само по себе open source сообщество и это как я понимаю просто ребята молодцы и своими силами собирают в одном месте информацию), есть кучи статей на хабре или видео на ютубе, но ни одного сайта не видел который можно было назвать официальным и первоисточником.
              Роман
              12 октября 2020, 18:06
              0
              Javascript — это одна из реализаций ECMA-262. Если вам нужно именно «официально-стандартно» — вам именно сюда.
              В 99% случаев вам будет удобнее всего ориентироваться на MDN, там все неплохо структурировано, и поддерживается в довольно актуальном состоянии.
        Баха Волков
        12 октября 2020, 14:26
        0
        Но если код выполнен, страница загрузилась, разве не должны все переменные быть очищены?
        Абсолютно нет. Пример для понимания, страница загрузилась, но остался код который срабатывает при определенных действиях пользователя, при истечении какого-то времени, с определенным интервалом и т.д.
          Александр Мельник
          12 октября 2020, 15:47
          0
          вы правы, просто я не вижу ничего подобного в документации.

          То что вы говорите, событие пользователя и прочее — все это асинхронность выполнения кода.
          Есть вот такой сайт
          latentflip.com/loupe/
          на котором наглядно отображается так называемый event loop для javascript в браузере, видно как асинхронные события помещаются в апи браузера, ждут наступления события, в то время как основной поток идет себе синхронно и так далее. И если в nodejs код всегда асинхронный, то в браузере (насколько я понимаю) нет, он наоборот всегда синхронный. Иначе нам не приходилось бы добавлять атрибут defer при подключении скрипта. При условии что мы не создаем асинхронности сами — добавляем промисы, колбеки и так далее.
          Поэтому мне казалось что было бы логично, что если весь код состоит из объявления и присвоения переменной, то после выполнения кода — прибить эту переменную в памяти. Но это так… лишь мои домыслы, а практика показывает что нет — все переменные продолжают храниться в оперативной памяти.

          А в каком тогда случае очищается память? Это где то задокументировано, вам попадалась такая инфа? При перезагрузке страницы? При закрытии вкладки?
            Роман
            12 октября 2020, 18:26
            +1
            Почитайте тут: Управление памятью
              Александр Мельник
              12 октября 2020, 18:36
              0
              пробежал одним глазом, выглядит вкусно! спасибо.
                Николай Савин
                12 октября 2020, 19:38
                0
                Наверное вот такие вопросы и возникают потому что все на бегу а не основательно и по порядку.
                Очень рекомендую уроки по JS Владилена Минина. У него превосходный канал на Ютубе с отличным контентом и есть полноценные курсы начиная от основ JS до всевозможных фреймворков. Ну и практика конечно.
                  Александр Мельник
                  12 октября 2020, 19:46
                  0
                  Спасибо) Как раз из видео Минина я и узнал о том, как работает event loop и асинхронность в js )
                  www.youtube.com/watch?v=vIZs5tH-HGQ
                    Александр Мельник
                    12 октября 2020, 19:48
                    0
                    пробежал одним глазом,
                    я имел в виду, что нет времени сейчас серьезно изучить и на выходных прочту и вникну.
                      Александр Мельник
                      12 октября 2020, 19:49
                      0
                      Хотя выбирая между Мининым и Лавриком… даже не знаю. Наверное остановлюсь на Лаврике, у него педагогический талант.
                        Александр Мельник
                        12 октября 2020, 20:04
                        0
                        Не соглашусь Николай насчет неосновательности и не по порядку.
                        Хотя у меня уже есть начальные знания о javascript, я прохожу учебник learn.javascript.ru/ пошагово, с первой главы. Иногда честно через силу, конкатенирую строчки, пишу if ы и прочий первоначальный синтаксис, хотя тянет сразу перейти к тому, что совсем прошло мимо меня — классы в js, модули, импорты экспорты и прочее. Но пока держу себя в руках.
                          Konstantin
                          12 октября 2020, 22:01
                          0
                          Я бы рекомендовал вместо learn.javascript.ru/ – developer.mozilla.org/ru/docs/Web/JavaScript
                            Александр Мельник
                            12 октября 2020, 22:18
                            0
                            спасибо. Я пользуюсь MDN, но больше как справочником, а не учебником.
                            Когда нужно понять как работает та или иная функция и так далее.
                            Все-таки учебник Кантора — это более учебное пособие, где после каждой главы есть закрепляющие занятия.
                Александр Мельник
                15 октября 2020, 17:59
                0
                Я продолжу задавать тут дилетантские вопросы по js.
                А почему в таком вот цикле (объект user заранее создан)
                for (const key in user) {
                            if (user.hasOwnProperty(key)) {
                                const element = user[key];
                                console.log(element);
                            }
                        }
                и key и element объявлены через const, хотя на каждой итерации они будут изменяться и при этом — ошибок не возникает?? Вот в моем понимании там может быть только let element =
                  Николай Савин
                  15 октября 2020, 19:36
                  0
                  1. Объект user просто определен выше по логике кода. Он не существует сам по себе. Читаем цикл for in
                  2. Переменные имеют область видимости. Она ограничена круглыми или фигурными скобками. Читаем область видимости. Попробуй вызови в консоли element за пределами ближайшей фигурной скобки
                  3. Как только область видимости заканчивается — сборщик мусора уничтожает переменную и ее можно объявить заново. В цикле можно заново объявлять переменные на каждой итерации. Читаем про сборщик мусора.
                  4. Есть такое правило ВСЕГДА использовать const при объявлении переменной. Это связано с тем что далее нельзя будет изменить ее тип и при объявлении четко понятно какого типа переменная. Исключение — если изначально понятно что переменная ниже будет перезаписана. И это объявление тоже служит сигналом для читающего код что где то ниже переменная будет перезаписана. Таким образом const и let это еще и информация о судьбе переменной. Будет ли ниже ее изменение.
                    Александр Мельник
                    15 октября 2020, 20:09
                    0
                    Кстати сегодня еще раз повторно читал главу о сборке мусора в js, так как эта темя меня интересует. Но каюсь я так и не понял, что сборщик мусора настолько «шустрый» что успевает отрабатывать на каждой итерации циклов. Там написано «Сборка мусора выполняется автоматически. Мы не можем ускорить или предотвратить её.» и плюс «чтобы уменьшить возможное влияние на производительность, сборщик мусора старается работать только во время простоя процессора.»
                    Но вы безусловно правы.
                      Александр Мельник
                      15 октября 2020, 20:36
                      0
                      Есть такое правило ВСЕГДА использовать const при объявлении переменной.
                      Я правильно понимаю — это не есть правило языка, это скорее «культура написания кода»? Просто некий инструмент, который позволяет гарантировать неизменность типа данных и значения (кроме объектов) если это зачем то нужно.

                      Опять таки, дилетансткое мнение ни о чем кроме размышлений не основанное, но мне кажется что в js так прижился const что даже стал негласным правилом, только потому что 90 процентов случаев в переменных лежат не примитивы, а объекты, а их свойства и методы можно менять и у const. И вроде как всем удобно. Потому как концепция «неизменяемая переменная» это странная идея и вообще — оксюморон какой-то.
                    Александр Мельник
                    15 октября 2020, 20:01
                    0
                    Спасибо Николай что не прошли мимо.
                    Тоесть я так понимаю, что в классическом цикле for const не прокатит, изза того что мы переменную i на каждой иттерации увеличиваем, а значит нам нужна ссылка на нее в памяти?
                    Так плохо
                    for (const i = 0; i < 10; i++) {
                                // do something
                            }
                    а так хорошо
                    for (let i = 0; i < 10; i++) {
                                //
                            }
                    далее нельзя будет изменить ее тип
                    Ну скорее значение? Тип понятное дело не измениться если нельзя заменить даже значение, но Боже мой, а с каких пор js стал языком со строгой типизацией? Такое чувство что из него C++ начали делать.
                      Николай Савин
                      15 октября 2020, 20:27
                      0
                      а так хорошо
                      да наверное. Вообще на моем опыте в счетчиках всегда let используют. Здесь как раз срабатывает правило — показать читающему что эта переменная где то далее изменится. Здесь не техническая особенность а скорее общепринятое написание.

                      Ну скорее значение?

                       Неа. Именно тип. Значение двух типов менять можно. Это массив и объект. Мы запросто можем манипулировать их внутренностями.
                        Александр Мельник
                        15 октября 2020, 20:40
                        0
                        Неа. Именно тип. Значение двух типов менять можно. Это массив и объект. Мы запросто можем манипулировать их внутренностями.
                        понимаю что занимаюсь демагогией бесполезной, но не соглашусь. Вы имеете ввиду что можете изменять значения свойств объекта, объявленного через const. А положить вместо этого объекта другой можете? Нет, хотя тип при этом вы же не измените. И у одного будет тип object и у второго.
                        Артем
                        16 октября 2020, 00:32
                        0
                        for (const i = 0; i < 10; i++) {
                        Этот вариант просто не будет работать, потому что ты мутируешь константу в выражении i++.
                        Это то же самое, что написать
                        const a = 1;
                        a++;
                        Именно поэтому используют let.

                        Я правильно понимаю — это не есть правило языка, это скорее «культура написания кода»?
                        Ты можешь использовать хоть var, но такой код никто не захочет читать и поддерживать. У const и let масса преимуществ перед var. Именно из-за них их и используют. Почитай про hoisting.

                        Потому как концепция «неизменяемая переменная» это странная идея
                        Отчего же это?
                          Александр Мельник
                          16 октября 2020, 09:16
                          0
                          Спасибо Артем.
                          вариант просто не будет работать, потому что ты мутируешь константу в выражении i++
                          я вроде бы именно это и написал, только без термина мутирования. Я написал «const не прокатит, изза того что мы переменную i на каждой итерации увеличиваем»
                          но такой код никто не захочет читать и поддерживать
                          — вроде бы тоже самое и я написал, что если язык позволяет так делать, то значит это НЕ есть «правило языка», это «культура написания кода», когда ты делаешь код гармоничнее и для себя и для потомков.
                          Отчего же это?
                          Лишь мои размышления. Название «переменная» намекает на изменяемость. Переменная должна «переменятся» или хотя бы иметь такую возможность.
                        Игорь
                        09 ноября 2020, 16:32
                        +1
                        Спасибо, с вами приятно работать. Недавно создавали корпоративный блог на moxd и со всей работой спаривлся наш програмист в одиночку причем. Все хорошо работает, удобно и много нужных настроек. За такими платформами будущее интернета. Наш сайт galeonyachtsforsale.com по продаже моторных яхт и катеров работает на немного устаревшей cms и в скором времени планируем переезжать на что то новое. Расматриваем разные варианты и mdox в их числе. Но пока не решили окончательно
                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                          31