JavaScript, часто сокращенно JS, — это язык программирования, который является одной из основных технологий Всемирной паутины, наряду с HTML и CSS. По состоянию на 2022 год 98% веб-сайтов используют JavaScript на стороне клиента для поведения веб-страниц, часто с использованием сторонних библиотек.

Что такое JS?

JavaScript (JS) это

  • динамический (также известный как нестрогий тип)
  • интерпретируется или компилируется (компилируется JIT)
  • со сбором мусора
  • однопоточный
  • мультипарадигма (функциональная и объектно-ориентированная)
  • язык программирования с функциями первого класса.

Примечание: к концу этого раздела вы сможете более подробно описать и объяснить JavaScript

Хотя он наиболее известен как язык сценариев для веб-страниц, многие небраузерные среды также используют его, например Node.js, Apache CouchDB и Adobe Acrobat. поддержка объектно-ориентированного, императивного и декларативного (например, функционального программирования) стилей.

Подробнее @ МДН

Кто и когда создал JS?

В 1995 году Брендон Эйх создал JS, чтобы добавить интерактивности в легендарный веб-браузер Netscape Navigator.

Зачем изучать JS?

JS был популярен, популярен, и с его постоянным развитием JS останется популярным.
См. самые популярные технологии @ Опрос StackOverflow 2022

Где использовать JS?

JS работает как в веб-браузере, так и вне его.

Как работает JS?

Чтобы понять, как работает JS, вам нужно понять

Понимание JS Engine

Практически все, кто работал с JS, слышали о JS Engine.

  • JS — это однопоточный язык, использующий обратные вызовы или Callback-Queue.
  • JS интерпретируется или компилируется?

Поэтому, если вы напишете какой-нибудь англоязычный оператор/код в своем JS-файле. И если вы напрямую предоставите этот JS-файл в качестве входных данных на свой компьютер, он может поднять флаг, что он понимает язык JS.

JS-движок будет принимать его в качестве входных данных и преобразовывать в выходные данные, более привычные для машины (машинный код).

концепции охватывают

  1. Внутри JS-движка
  2. куча
  3. Стек вызовов

Внутри JS Engine

Итак, мы узнали, что JS Engine — это тот, кто берет наш JS-файл/код и преобразует его в машинный код, чтобы он был понятен машине. Давайте заглянем внутрь популярного движка, используемого Chrome и NodeJS, то есть Google V8 JS Engine.

Поэтому, когда вы передаете файл JS движку JS для его запуска

  • Синтаксический анализатор: выполняет лексический анализ, который разбивает код на то, что называется грамматикой/ключевыми словами JS на основе токенов, чтобы определить значение кода и определить, что код пытается сделать.

  • AST: эти токены затем формируют AST (абстрактное синтаксическое дерево). Инструмент › https://astexplorer.net/. AST выглядит для людей тарабарщиной, но позволяет JS Engine понять, что пытается сделать код.
  • Интерпретатор: переводите исходный код в машинный код, выполняйте его, читая построчно. Конечно, исходный код еще нужно преобразовать в машинный код, но это просто происходит непосредственно перед его выполнением, а не раньше времени.

  • Интерпретатор начинает читать исходный код сверху вниз, сначала он читает строку 1 и понимает, что объявлена ​​функция someCalculation, затем строку 2, затем строку 3, понимает тело функции и, наконец, выполняет его, прежде чем перейти к строке 4.
  • и в строке он читает ключевое слово for и понимает, что цикл for объявлен следующим образом: читает строку 4 и строку 6 и понимает выражение, которое ему нужно повторить, и, наконец, выполняет цикл for перед переходом к следующей строке исходного кода (какой EOF в нашем случае)
  • затем для каждой итерации цикла будет выполняться строка 1, затем строка 2, затем строка 3.
  • Примечание в этом подходе, несмотря на то, что результат someCalculation остается неизменным, функция выполняется для каждой итерации.
  • Profiler: рассматривается в следующем разделе.
  • Компилятор: переводит исходный код в машинный код, делает это, читая исходный код за один раз и выполняя его. связанный с машинным кодом т.е. понятный моей машине)

например, обратите внимание на ввод и вывод компилятора ниже

Интерпретатор или компилятор?

Переводчик

  • Быстрее вставать и работать
  • Но он становится медленнее в исполнении, так как не выполняет никакой оптимизации в случае огромного кода JS.

Компилятор

  • Медленнее вставать и работать
  • Но он быстрее в исполнении, так как выполняет какую-то оптимизацию в случае огромного кода JS.

Можем ли мы взять лучшее из обоих миров?

Компилятор JIT, давайте разберемся, как это делает движок Google v8

Изначально

Исходный код -> Синтаксический анализ -> AST -> Интерпретатор -> байт-код (также известный как зажигание, т.е. для выполнения нашего кода как можно скорее)

  • Профилировщик: отслеживает и наблюдает за выполнением кода и делает заметки о том, как мы можем оптимизировать этот код: сколько раз он выполнялся? какие виды используются? Как это можно оптимизировать?
  • Теперь, когда байт-код от интерпретатора выполняется, копия исходного кода передается компилятору вместе с примечаниями по оптимизации от профилировщика и генерирует оптимизированный байт-код.
  • Это означает, что код JS, предоставленный движку V8, будет постепенно улучшаться, потому что профилировщик и компилятор постоянно улучшают байт-код по мере работы приложения, то есть почему он называется JIT-компилятором.
  • Наконец, он смешивает и сопоставляет или заменяет байт-код от интерпретатора оптимизированным байт-кодом от компилятора для запуска на машине, и это постоянно проходит через этот цикл. Компилятор во время работы приложения принимает байт-код

Интерпретатор JS интерпретируется?

Да, изначально, когда JS впервые появился, JS Engine, такой как SpiderMonkey, созданный Брендоном Эйхом, интерпретировал JS в байт-код, и этот движок мог работать внутри нашего браузера, чтобы сообщать нашим компьютерам, что делать. Но теперь все изменилось, чтобы использовать профилировщик и компилятор, также известный как JIT-компилятор, для оптимизации этого кода.

Компилятор JS скомпилирован?

Да, это зависит от реализации современного JS Engine.

JIT-компилятор JS компилируется JIT?

Да, например, движок v8 от Google

До сих пор мы узнали, что JS Engine делает за нас много работы, но более важным является чтение нашего кода и его выполнение, которое состоит из 2 самых важных шагов.

  • куча
  • Стек вызовов

Знакомство с кучей

Место для хранения и записи информации (переменные, объекты и т.д.) -> куча памяти -> используется движком JS для выделения памяти

Утечки памяти

Выполните приведенный выше код на вкладке консоли инструментов разработчика в Chrome и посмотрите, что произойдет.

3 распространенные утечки памяти

Понимание стека вызовов

Место для хранения и отслеживания того, что происходит построчно в нашем коде — › Стек вызовов — используется движком JS для отслеживания того, где находится ваш код во время выполнения.

  • Запустите приведенный выше код как фрагмент на вкладке «Источник» консоли разработчика Chrome.

  • Обратите внимание, когда вы выполняете сценарий с помощью отладчика, сценарий приостановлен в отладчике и даже до вызова функции calc в стеке вызовов есть что-то с именем → анонимный, также известный как глобальный контекст выполнения, который будет обсуждаться в следующих темах.

  • Когда вы нажимаете шаг F11 2 раза, метод subtractTwo также помещается в стек вызовов.

Мы не закончили выполнение calc(), вместо этого calc() вызывается subtractTwo(), а стек вызовов отслеживает выполнение кода. Четко глядя на стек вызовов, я могу сказать, что мы subtractTwo().

  • Когда вы снова нажмете шаг F11, метод calc завершится выполнением и выскочит из стека вызовов.
  • Наконец, вы можете нажать F8 (возобновить выполнение скрипта).

Понимание переполнения стека

Наиболее распространенным способом создания переполнения стека является использование рекурсии. Например,

Выполните приведенный выше код на вкладке консоли в инструментах разработки в Chrome.

Вывоз мусора

  • JS — это язык со сборщиком мусора.

  • Когда JS выделяет память, то есть внутри функции, которую мы создали, объект автоматически сохраняется где-то в нашей куче памяти, когда JS завершает выполнение моей функции, и, скажем, нам больше не нужен этот объект.
  • JS автоматически очистит его для нас и освободит кучу памяти, поэтому останутся только те данные, которые нам полезны, т. е. на которые все еще ссылается моя программа. Это гарантирует, что мы не используем всю доступную память, поскольку мы знаем, что память ограничена.
  • Таким образом, в языке со сборкой мусора, таком как JS, сборщик мусора освобождает память кучи и предотвращает то, что мы называем утечками памяти.

Означает ли это, что вы полностью полагаетесь на сборщик мусора для управления памятью кучи?

Как работает сборка мусора в JS?

Работает по алгоритму Mark and Sweeps.

На объект больше не ссылается переменная human, что делает его пригодным для сборки мусора после выполнения кода в строке 5

После выполнения logHuman() объект, на который ссылается человеческая переменная, подлежит сборке мусора

Другими словами, мы можем сказать, что область действия человеческого объекта заканчивается после выполнения logHuman().

Один поток

Однопоточность означает, что одновременно выполняется только один набор инструкций, а не выполнение нескольких действий. Причина однопоточности -> заключается в том, что у нее есть только 1 стек вызовов.

В чем проблема с однопоточным языком?

Запустите приведенный выше код на вкладке консоли в инструментах разработки Chrome.

Почему кто-то хочет заблокировать свое приложение?

Вы не думаете, что синхронное поведение JS делает его менее популярным?

Большую часть времени вы не будете напрямую обращаться или использовать JS Engine (который является синхронным). Нам нужно представить идею асинхронного кода. Не только движок JS выполняет наш код, но и среда выполнения JS (NodeJS реализует нечто подобное), которая выходит за рамки только движка JS.

Понимание среды выполнения JS

Чтобы преодолеть однопоточный характер JS, на сцену вышла JS Runtime.

Среда выполнения JS состоит из 3 основных компонентов.

движок JS — уже рассмотрено

Веб-API браузера

Это приложения, которые могут делать множество вещей, таких как отправка HTTP-запросов, прослушивание событий DOM (щелчок, изменение), setTimeout, хранилище сеансов localStorage, indexedDB и т. д.) — все это асинхронные операции.

Таким образом, браузеры используют LLL, например C++, вместо JS Engine и блокируют поток для выполнения этих асинхронных операций в фоновом режиме, и эти API называются веб-API (которые являются асинхронными, что означает, что они что-то делают в фоновом режиме и возвращают данные обратно в JS-движок)

Цикл событий и стек обратных вызовов

Среда выполнения JS в действии

  • У нас есть элементы в стеке вызовов, и как только появляется что-то вроде setTimeout, т.е. не часть JS, а часть веб-API
  • Стек вызовов скажет: «У меня есть кое-что, что не для меня, это для веб-браузера (веб-API). Итак, он говорит: «Привет, веб-API, это что-то для вас, я не знаю, что с этим делать, пожалуйста, позаботьтесь об этом». этого и делайте это в фоновом режиме »
  • Как только (setTimeout) асинхронная операция будет обработана веб-API, она отправит данные (обычно обратный вызов) асинхронной операции в очередь обратного вызова.
  • Цикл событий постоянно проверяет, есть ли какой-либо обратный вызов в очереди обратного вызова и является ли стек вызовов пустым или нет. Если стек вызовов пуст, тогда цикл событий будет извлекать обратный вызов из очереди обратного вызова и помещать его в стек вызовов, а теперь и в JS. Двигатель выполнить его.

👉 Скрытый инструмент переворота

Кратко объясните, что такое JS, JS Engine и JS Runtime?

JS › Музыкальные ноты

JS Engine › Музыкальный композитор

JS Runtime › Музыкальный оркестр

Первоначально опубликовано на https://nikhilrstg18.github.io.