- PVSM.RU - https://www.pvsm.ru -
Доброго времени суток, друзья!
Представляю вашему вниманию перевод заметки Nikhil John «console.log isn’t in the JavaScript language» [1].
Пожалуй, console.log является самой используемой командой в JS. Однако она не является частью JS. Не верите? А вы загляните в спецификацию ECMAScript2015 [2].
После того как я вас заинтриговал (потому что вы не обнаружили упоминания о console в ES6), позвольте мне продолжить.
То, что называют JS в браузере/на сервере, это лишь среда выполнения JS. Эта среда представляет собой так называемый «движок» JS (V8 в Chrome и NodeJS, SpiderMonkey в Firefox, JavaScriptCore в Safari).
Среда выполнения JS = движок JS (JS Runtime) + цикл событий (Event Loop) + внешние API + очередь функций обратного вызова (Callback Queue; далее — очередь).
Примечание: цикл событий, в зависимости от реализации, может входить в движок JS.
Объект console — это Web API, предоставляемый в распоряжение движка JS браузером, наряду с такими API, как DOM, Fetch, History, Service Workers и Web Storage. JS работает как в браузере, так и на сервере, и каждый из них имеет собственную реализацию console. Части JS, которые являются стандартными для всех сред выполнения, подробно описываются в спецификациях ECMA (речь идет о таких вещах, как «примитивы», типы данных, грамматика и синтаксис языка, арифметические и логические операции, встроенные объекты и функции и т.д.). Это означает, что одни вещи, такие как, например, Array.isArray(), встроены в JS, другие, такие как setTimeout(), нет.
Давайте посмотрим на реализации console в разных средах выполнения (сперва — Chrome v78, затем — Node v10, оба работают на V8):
Реализация Node по сравнению с реализацией Chrome имеет парочку дополнительных методов (markTimeline, timeline, timelineEnd), хотя обе среды выполнения основаны на спецификации ECMA. Реализация console в Firefox также будет отличаться от представленных.
Почему это важно? Для того, чтобы понять, как работает JS, нужно знать, как язык взаимодействует со средой, в которую он встроен.
В действительности JS является однопоточным и синхронным языком.
Асинхронные операции (setTimeout, setInterval и др.) предоставляются и реализуются средой выполнения.
В браузере выполнение JS-кода имеет примерно следующий вид (спасибо Philip Roberts за Loop [3]). Обратите внимание, что JS или V8 — прямоугольник под названием «стек вызовов» (Call Stack) слева. Web API и очередь — компоненты среды выполнения браузера.
Это называется параллельной моделью выполнения событий или «Как однопоточный синхронный JS выполняет несколько (якобы) одновременных асинхронных операций». Это также объясняет ответ на популярный вопрос о том, почему код
console.log('Первый')
setTimeout(() => console.log('Второй'), 0)
console.log('Третий')
… выводит
Первый
Третий
Второй
… а не
Первый
Второй
Третий
JS выполняет каждую команду синхронно, одну за другой. Любой оператор с функцией обратного вызова (как, например, setTimeout) обрабатывается точно также, однако функция обратного вызова помещается в очередь.
Поскольку setTimeout — это Web API, он запускает внешний таймер в браузере вне среды выполнения JS. Может показаться, что JS выполняет «отложенный» код позже, но вот что происходит на самом деле:
Вот и все, теперь мы знаем, как однопоточный синхронный JS выполняет асинхронные операции. Вся соль — во внешних API.
Счастливого кодинга!
Также см. серию статей [4] о том, как работает JS, от @ru_vds [5] и заметку «Парочка интересных методов объекта Console» [6].
Автор: aio350
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/347069
Ссылки в тексте:
[1] «console.log isn’t in the JavaScript language»: https://medium.com/swlh/console-log-isnt-in-the-javascript-language-2b0f24d57397
[2] ECMAScript2015: http://www.ecma-international.org/ecma-262/6.0/
[3] Loop: http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D
[4] серию статей: https://habr.com/ru/company/ruvds/blog/337042/
[5] @ru_vds: https://habr.com/ru/users/ru_vds/
[6] «Парочка интересных методов объекта Console»: https://habr.com/ru/post/484544/
[7] Источник: https://habr.com/ru/post/488914/?utm_campaign=488914&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.