Язык JavaScript

Язык JavaScript

JavaScript – язык многофункциональный интерпретируемый язык программирования с объектно-ориентированными возможностями. Появился он в 1995 г. как часть некогда самого популярного в то время браузера Netscape Navigator; разработчик Брендан Эйх (Brendan Eich), сотрудник компании Netscape. Главная задумка языка состояла в том, чтобы с его помощью сделать веб-страницы динамическими, что невозможно используя только HTML. JavaScript позволяет на веб-странице выполнять вычисления, взаимодействовать с пользователями, реагировать на события, получать и использовать данные из Интернета, выводить графику и многое другое. Потом JavaScript появился в других распространённых браузерах. В настоящее время JavaScript используется в качестве фронтенд-языка на 97% сайтов, поскольку ему практически нет альтернативы, а кроме этого он нужен и для мобильных приложений.

JavaScript стандартизован ассоциацией ECMA, описан в стандарте ECMA-262 (существуют различные версии стандарта, последняя пятая) и согласно ему язык официально называется ECMAScript. Но этим неудобным названием мало кто пользуется, обычно только в случае, если необходимо явно сослаться на стандарт. В дополнение к спецификациям ECMA-262 ассоциация ECMA разработала ещё стандарт ECMA-357, в котором было стандартизовано расширение JavaScript, известное под названием E4X, или ECMAScript for XML. С помощью этого расширения в язык была добавлена возможность манипулировать XML-документами. ECMAScript 2022 – это новый стандарт JavaScript, который был выпущен в июне 2022 года.

JavaScript тесно связан с языком гипертекстовой разметки HTML (Hypertext Markup Language), который используется для форматирования контента страниц, задания их структуры: абзацев, заголовков и разделов и т.д. Поэтому код JavaScript упакован в разметку HTML. Ниже приведена простая страница HTML, которая показывает пример такой упаковки:


<!DOCTYPE html>

<html lang="en">

   <head>

          <meta charset="utf-8">

          <title>Заголовок вашей HTML-страницы </title>       

          <script>

           Ваш код JavaScript обычно размещается здесь

          </script>

     </head>   

     <body>

Содержимое веб-страницы размещается здесь.

     </body>

</html>

 

Таким образом, программист включает код на JavaScript прямо в веб-страницу, которая потом загружается в браузер. Никакой компилятор или интерпретатор вызывать не надо – браузер сам сделает всё необходимое для исполнения написанного кода. Эта встроенная версия JavaScript запускает сценарии, внедренные в HTML-код веб-страниц, и называется клиентским языком JavaScript, чтобы подчеркнуть, что сценарий исполняется на клиентском компьютере, а не на веб-сервере. О серверном JavaScript, такой тоже есть, я расскажу отдельно.

Для отладки HTML-файл с кодом на JavaScript нужно просто загрузить с диска в браузер и он будет исполнен. Более того, в HTML-страницу можно включить файл (например, code.js) с JavaScript-кодом.

<script src="code.js"></script>

Тут можно ещё упомянуть, что совместно с HTML, чтобы определить стиль оформления, отделённый от структуры страницы, используется технология каскадных таблиц стилей CSS (Cascading Style Sheets), которая позволяет определить цвета, шрифты, границы, макет страницы. Вещь необходимая веб-мастеру, но с этим ему ещё нужно научиться работать. Это к тому, что JavaScript включается в HTML-страницу точно так же, как и CSS, т. е. он просто встраивается прямо в документ в тегах <script>.

Появились встроенные реализации JavaScript, существующие отдельно от браузеров. Это JavaScript Engine – движок, который может выполнять программу на JavaScript, в том числе на сервере. Один из самых популярных, движок с открытым исходным кодом V8 – был разработан корпорацией Google, он написан на С++; содержит JIT-компилятор, транслирующий исходный текст на JavaScript машинный код, который тут же оптимизируется и выполняется. Можно отметить и Rhino – также движок с открытым исходным кодом, написанный на Java. Разработан компанией Mozilla.

Движок SpiderMonkey – SpiderMonkey был написан Бренданом Айком во время его работы в Netscape Communications, а позднее сделан открытым. В настоящее время SpiderMonkey поддерживается компанией Mozilla Foundation. Наконец, JavaScriptCore – движок с открытым исходным кодом, разработанный корпорацией Apple для веб-браузера Safari.

Среди других языков, отмечу Jscript и Microsoft JScript.NET – это адаптации JavaScript, выполненные Microsoft. Многие языки транскрибируются в JavaScript. Это в первую очередь TypeScript, Dart, Elm, PureScript и CoffeeScript.

Важная особенность JavaScript – безопасность. JavaScript не может получить доступ к памяти компьютера и к процессору, на котором исполняется скрипт напрямую. Нет доступа и к файловой системе, Когда JavaScript выполняется в браузере, он имеет доступ к специальным браузерным API, и работает через них. Для доступа к оборудованию, например к микрофону, видеокамере, нужно постоянно получать подтверждение от пользователя.

С точки зрения синтаксиса язык JavaScript напоминает C, C++ и Java такими программными конструкциями, как if, цикл while, операторами && и ||, и др. Одно из наиболее распространённых заблуждений о JavaScript состоит в том, что этот язык представляет собой упрощённую версию языка Java. Однако это совсем не так и, кроме указанной выше синтаксической схожести, эти два языка между собой почти ничто не связывает – первоначальное название языка – LiveScript было изменено на JavaScript по просьбе маркетологов. Наконец, приложения, написанные на JavaScript, можно отлаживать прямо в браузере. (Имеются и более развитые отладчики – можно воспользоваться отладчиком Microsoft Script Debugger в Internet Explorer, а в Firefox – модулем расширения Venkman.)

При написании программ на JavaScript используется набор символов Unicode. JavaScript – это нетипизированный язык, т. е. в нём не требуется определять типы переменных, типизация слабая и динамическая.

Ядро языка JavaScript поддерживает работу с такими простыми типами данных, как числа, строки и булевы значения, обладает также встроенной поддержкой массивов, дат и объектов регулярных выражений. Встроенные типы данных соответствуют таковым в других ЯВУ, кроме целых чисел. Они могут быть представлены в очень большом диапазоне от –9007199254740992 ( –253) до +9007199254740992 (253) включительно. Вне этого диапазона может теряться точность в младших разрядах целых чисел. Из отличий в типах данных отмечу, в JavaScript нет типа данных, такого как char в C, C++ и Java. Одиночный символ представлен строкой единичной длины.

Объявление переменной всегда начинается с ключевого слова var. Имя переменной должно начинаться с буквы, подчеркивания или знака доллара. В JavaScript регистр символов учитывается в именах переменных, ключевых словах, именах функций. Имена переменных, начинающиеся с $, обычно резервируются для библиотек JavaScript. Если начальное значение переменной не указано, JavaScript по умолчанию присваивает ей значение undefined, сообщая, что «переменная ещё не инициализирована».

Переменные делятся на локальные и глобальные. Специфика JavaScript в том, что если используется переменная, которая не была ранее объявлена, такая переменная будет считаться глобальной. Глобальные переменные существуют, пока существует веб-страница. Жизнь глобальной переменной начинается с момента загрузки кода JavaScript для страницы. Когда страница перестает существовать, то перестают существовать и глобальные переменные. Даже если перезагрузить эту страницу, все глобальные переменные будут уничтожены и созданы заново в перезагруженной браузером странице. Ещё одна особенность – если используется переменная, которая не была ранее объявлена, такая переменная считается глобальной. А если она оказалась внутри функции, то возможен неприятный сюрприз.

Классическая первая программа на JavaScript выглядит так:

<script>

alert('Hello, World!');

</script>

 

JavaScript предоставляет несколько синтаксических конструкций для повторного выполнения кода: while, for, for in и forEach. Примеры:

var ps = 5;

while (ps > 0) {

    document.write("Ещё одно исполнение цикла<br>");

    ps = ps - 1;

}

На этом примере видно, что в текст на JavaScript могут быть включены теги языка HTML, в данном случае <br> -- перевод строки. Веб-страница рассматривается браузером как документ, поэтому функция document.write позволяет вывести произвольную разметку HTML и контент в произвольной точке страницы.

 

var fact = 1;

for(i = 1; i < 10; i++) {

   fact = fact*i;

   document.write(i + "! = " + fact + "<br>");

}

 

В этой конструкции всё похоже на конструкции цикла в обычных процедурных ЯВУ.

 

JavaScript поддерживает работу с одномерными массивами, а поскольку он является нетипизированным языком, то элементы массива не обязательно должны иметь одинаковый тип – в отличие от многих других языков, в массиве могут храниться практически любые значения JavaScript, включая строки, числа, логические значения, другие массивы и даже объекты. Так команда:

 

var myarray = new Array(5);

 

с помощью конструктора Array создает новый массив пятью пустыми позициями (то есть массив длины 5, который не содержит ни одного значения).

В JavaScript добавлена концепция «итерируемых» (iterable) объектов. Итерируемые или, иными словами, «перебираемые» объекты – это те, содержимое которых можно перебрать в цикле. Перебираемым объектом является массив. Но не только он. В браузере существует множество объектов, которые не являются массивами, но содержимое которых можно перебрать (к примеру, список DOM-узлов). Для перебора таких объектов добавлен новый синтаксис цикла: for..of.

 

let arr = [1, 2, 3, 4]; // массив — пример итерируемого объекта

 

for (let value of arr) {

alert(value); // 1, затем 2, затем 3, затем 4

}

Практически везде, где нужен перебор, он осуществляется через итераторы.

 

JavaScript передает аргументы функциям по значению. Это означает, что каждый аргумент копируется в переменную-параметр и любые изменения параметра в функции затрагивают только сам параметр, но не исходную переменную. При этом функция игнорирует лишние аргументы, а параметрам, не получившим аргументов, присваивается значение undefined. Функция без команды return вернёт undefined.

Обычно в ЯВУ определение функции должно предшествовать её использованию. В JavaScript, из-за того что браузер обрабатывает веб-страницу дважды – при первом проходе он читает все определения функций, а при втором выполняет код, размещать функции можно в любом месте файла даже после их использования программе.

 

Работа с объектами в JavaScript похожа на работу с ними в других объектно-ориентированных языках, но есть некоторые особенности, в частности, многие JavaScript-объекты и их свойства имеют те же имена, что и теги и атрибуты языка HTML, которые они обозначают, т. е. в дополнение к встроенным в браузер объектам, можно определить свои собственные объекты. Отметим, что сам JavaScript предоставляет множество готовых объектов, которые можно использовать в своём коде, в то же время программисту доступны и объекты самого браузера. Свойства объекта можно динамически добавлять к нему и удалять. Доступ к свойству можно получить с помощью точечной записи:

 

objectName.propertyName

 

или с помощью скобочной записи

 

objectName["propertyName"] = value

 

Все объекты в JavaScript наследуются как минимум от другого объекта. Объект, от которого произошло наследование, называется прототипом.

При написании приложений для браузера ключевую роль играют такие объекты браузера как

  • document – служит для записи из программного кода в веб-страницу;

  • метод log объекта console используется для вывода сообщений на консоль;

  • Window представляет свойства, относящиеся к браузеру. На самом деле это очень важный объект – через него JavaScript подтягивает себе все объекты и методы, имеющиеся в браузере. В других ЯВУ это делается через набор многочисленных библиотек.

Программа на JavaScript взаимодействует с веб-страницей, используя объектную модель документа DOM (Document Object Model). Рассмотрим, что это такое. При загрузке страницы браузер разбирает её HTML-разметку, выводит страницу на экран, и создает при этом набор объектов, представляющих разметку. Эти объекты и сохраняются в модели динамически. Код JavaScript взаимодействует с DOM для получения доступа к элементам разметки и их содержимому как для создания, чтения, так и для удаления элементов. При любом изменении DOM браузер сразу же обновляет страницу.

Корнем каждой модели DOM является объект document, а под ним располагается дерево с ветвями и листовыми узлами для всех элементов разметки HTML. Объект document может использоваться в JavaScript для получения доступа ко всей модели DOM.

 

Например, найти на странице идентификатор абзаца с именем EC1045:

var computer = document.getElementById("EC1045");

Метод getElementById ищет элемент EC1045 и возвращает его.

 

Свойство innerHTML используется для чтения и замены содержимого элемента. В innerHTML возвращается внутреннее содержимое элемента, без тегов HTML. Заменим содержимое элемента EC1045:

computer.innerHTML = "Организация-разработчик: НИИММ, Ереван.";

Содержимое элемента EC1045 заменяется новым текстом, DOM и страница обновляются, а новый текст появляется в браузере.

Встроенный объект document содержит целый набор свойств и методов, с которыми достаточно плотно придётся работать JavaScript-программисту. Но это планида всех, кто занимается веб-разработкой на скриптовых языках, т. е. нужно глубоко погрузиться в HTML5, CSS и освоить некоторое множество методов и свойств JavaScript и браузеров. Замечу, что последние новости о JavaScript несколько настораживают – сверхбольшую нейросетевую модель GPT 4.0 научили писать простые сценарии на этом языке (и ещё почти на десятке других). Я попросил GPT 4.0 написать на JavaScript программу, реализующую так называемое шифрование кодом Цезаря. Получил вот такой текст:
def caesar_cipher(text, shift):

    cipher_text = ""

    for char in text:

        if char.isalpha():

            # Получаем номер символа в алфавите

            char_num = ord(char.lower()) - ord('a')

            # Сдвигаем номер символа на указанное количество позиций

            shifted_char_num = (char_num + shift) % 26

            # Получаем символ из сдвинутого номера

            shifted_char = chr(shifted_char_num + ord('a'))

            # Делаем символ заглавным, если он был таковым в первоначальном тексте

            if char.isupper():

                shifted_char = shifted_char.upper()

            cipher_text += shifted_char

        else:

            cipher_text += char

    return cipher_text

 

Пример использования функции:

 

text = "Hello, World!"

shift = 5

cipher_text = caesar_cipher(text, shift)

print("Encrypted:", cipher_text)  # "Mjqqt, Btwqi!"

 

original_text = caesar_cipher(cipher_text, -shift)  # сдвигаем на обратное значение назад

print("Decrypted:", original_text)  # "Hello, World!"

 

Конечно, выдаваемый моделью код нужно тщательно проверять, но такая возможность может заметно ускорить разработку приложений.

Продолжим. Если щёлкнуть на веб-странице правой кнопкой мыши, то в появившемся ниспадающем меню вы увидите пункт «Показать код страницы». Код страницы появится либо в правой части окна, либо займет всё окно. В большинстве случаев это будет код на JavaScript, внедрённый в HTML-текст. Следует выбирать наиболее простые страницы, так называемые визитницы, поскольку иначе это будет довольно гремучая и трудно читаемая смесь.

Теперь о серверном JavaScript. Он имеет то же самое языковое ядро, что и клиентский JavaScript. Но, поскольку на сервере другая среда, то и JavaScript работает в ней иначе. Среди задач, которые могут быть запрограммированы в серверной среде, может быть установление соединения с реляционной базой данных, работа с файловой системой сервера и др. А это уже совсем другие объекты. Так серверный JavaScript включает объект database для соединения с внешней реляционной БД. Кроме того, серверное приложение может обрабатывать запросы от тысяч пользователей и работать с громадными объёмами данных. Серверный код JavaScript заключен в специальный тег </server> языка HTML, т. е. на странице может располагаться код, который будет выполняться либо на клиенте (тег </script>), либо на сервере. Поскольку задачи у клиентского и серверного JavaScript разные, то для каждой из сторон имеется свой большой набор предопределённых классов и объектов, которые исполняются только на конкретной стороне, но не работают на другой стороне. Но в целом, несмотря на перечисленные чудачества, JavaScript вполне элегантный и приятный язык.


Москва, май 2023 г.

Автор благодарен Владимиру Биллигу, инициатору написания этого текста и сделавшему по нему ряд полезных замечаний.

Об авторе: Директор Виртуального Компьютерного Музея
Помещена в музей с разрешения автора 2 июня 2023