27 июл 2022 · 03:06    
{"document": [{"text": [{"type": "string", "attributes": {"italic": true}, "string": "Новые возможности ECMAScript 2022 включают в себя ожидание на верхнем уровне, индексы соответствия RegExp, новые поля классов public и private и многое другое. Давайте приступим!"}], "attributes": []}, {"text": [{"type": "attachment", "attributes": {"presentation": "gallery"}, "attachment": {"caption": "", "contentType": "image/jpeg", "filename": "imgpreview.jpg", "filesize": 80606, "height": 540, "pic_id": 108613, "url": "/files/article_image/2022/07/27/imgpreview_JMSsPTE.jpeg", "width": 960}}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "ECMAScript 2022 (ES13) был выпущен 22 июня и содержит последнюю партию новых функций для Javascript. Каждая технологическая спецификация - это веха в непрерывном танце с реальным использованием. Спецификация ECMAScript реагирует на это, формализуя новые возможности. Они, в свою очередь, устанавливают новый базовый уровень для дальнейшего развития JavaScript."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Спецификация ES13 привносит "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposals/blob/main/finished-proposals.md"}, "string": "восемь новых возможностей для JavaScript"}, {"type": "string", "attributes": {}, "string": ". Давайте начнем знакомство с этими новыми возможностями, которые вы можете использовать уже сегодня."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Поля классов"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-class-fields"}, "string": "Поля классов"}, {"type": "string", "attributes": {}, "string": " - это зонтичное предложение, которое включает в себя несколько улучшений для работы с членами классов JavaScript: "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-class-fields"}, "string": "публичные и приватные поля экземпляра класса"}, {"type": "string", "attributes": {}, "string": ", "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-private-methods"}, "string": "приватные методы и аксессоры экземпляра"}, {"type": "string", "attributes": {}, "string": ", а также "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-static-class-features"}, "string": "статические функции класса"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Публичные и приватные поля экземпляра"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Ранее стандартным подходом при объявлении поля-члена внутри ключевого слова "}, {"type": "string", "attributes": {"bold": true}, "string": "class "}, {"type": "string", "attributes": {}, "string": "было введение его в конструктор. Новейшая спецификация ECMAScript позволяет нам определять член встраиваемого поля как часть тела класса. Как показано в примере 1, мы можем использовать хэштег для обозначения приватного поля."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 1. Совмещаем публичные и приватные поля класса:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "class"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": " {\ntitle = «»;\n#"}, {"type": "string", "attributes": {"italic": true}, "string": "artist = «»;"}, {"type": "string", "attributes": {}, "string": "\nconstructor(title, artist){\n"}, {"type": "string", "attributes": {"bold": true}, "string": "this"}, {"type": "string", "attributes": {}, "string": ".title = title;\n"}, {"type": "string", "attributes": {"bold": true}, "string": "this"}, {"type": "string", "attributes": {}, "string": ".#artist = artist;\n}\n}\n"}, {"type": "string", "attributes": {"bold": true}, "string": "let"}, {"type": "string", "attributes": {}, "string": " song1 = "}, {"type": "string", "attributes": {"bold": true}, "string": "new"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": "(«Only a Song», «Van Morrison» );\nconsole.log(song1.title);\n"}, {"type": "string", "attributes": {"italic": true}, "string": "// outputs “Only a Song”"}, {"type": "string", "attributes": {}, "string": "\nconsole.log(song1.artist);\n"}, {"type": "string", "attributes": {"italic": true}, "string": "// outputs undefined"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {}, "string": "В первом примере мы определяем класс "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": ", используя ключевое слово "}, {"type": "string", "attributes": {"bold": true}, "string": "class"}, {"type": "string", "attributes": {}, "string": ". Этот класс имеет два члена, название и исполнитель. Член "}, {"type": "string", "attributes": {"bold": true}, "string": "artist "}, {"type": "string", "attributes": {}, "string": "имеет префикс в виде символа хэша, поэтому он является приватным. Мы разрешаем устанавливать эти поля в конструкторе. Обратите внимание, что конструктор должен обращаться к "}, {"type": "string", "attributes": {"bold": true}, "string": "this.# artist"}, {"type": "string", "attributes": {}, "string": " с префиксом хэша еще раз, иначе он перезапишет поле публичным членом."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Далее мы определяем экземпляр класса "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": ", устанавливая оба поля через конструктор. Затем мы выводим поля в консоль. Дело в том, что "}, {"type": "string", "attributes": {"bold": true}, "string": "song1.artist"}, {"type": "string", "attributes": {}, "string": " не виден внешнему миру и выводит неопределенное значение."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Заметим также, что даже "}, {"type": "string", "attributes": {"bold": true}, "string": "song1.hasOwnProperty(«artist» )"}, {"type": "string", "attributes": {}, "string": " вернет "}, {"type": "string", "attributes": {"bold": true}, "string": "false"}, {"type": "string", "attributes": {}, "string": ". Кроме того, мы не сможем создать приватные поля класса позже с помощью присваивания."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "В целом, это приятное дополнение, делающее код чище. Большинство браузеров уже давно поддерживают публичные и приватные поля экземпляра, и приятно видеть их официальное включение."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Методы и аксессоры частных экземпляров"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": ""}, {"type": "string", "attributes": {}, "string": "Символ хэша также работает как префикс для методов и аксессоров. Влияние на видимость точно такое же, как и в случае с приватными полями экземпляра. Так, вы можете добавить приватный сеттер и публичный геттер к полю "}, {"type": "string", "attributes": {"bold": true}, "string": "Song.artist"}, {"type": "string", "attributes": {}, "string": ", как показано в примере 2."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 2. Методы и аксессоры частных экземпляров:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "class"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": " {\ntitle = «»;\n#"}, {"type": "string", "attributes": {"italic": true}, "string": "artist = «»;"}, {"type": "string", "attributes": {}, "string": "\nconstructor(title, artist){\n"}, {"type": "string", "attributes": {"bold": true}, "string": "this"}, {"type": "string", "attributes": {}, "string": ".title = title;\n"}, {"type": "string", "attributes": {"bold": true}, "string": "this"}, {"type": "string", "attributes": {}, "string": ".#artist = artist;\n}\n"}, {"type": "string", "attributes": {"bold": true}, "string": "get"}, {"type": "string", "attributes": {}, "string": " getArtist() {\n"}, {"type": "string", "attributes": {"bold": true}, "string": "return"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "this"}, {"type": "string", "attributes": {}, "string": ".#artist;\n}\n"}, {"type": "string", "attributes": {"bold": true}, "string": "set "}, {"type": "string", "attributes": {}, "string": "#"}, {"type": "string", "attributes": {"italic": true}, "string": "setArtist(artist) {"}, {"type": "string", "attributes": {}, "string": "\n"}, {"type": "string", "attributes": {"bold": true}, "string": "this"}, {"type": "string", "attributes": {}, "string": ".#artist = artist;\n}\n}"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Статические члены"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Предложение о полях класса также вводит статические члены. Они выглядят и работают аналогично тому, как это делается в "}, {"type": "string", "attributes": {"bold": true}, "string": "Java"}, {"type": "string", "attributes": {}, "string": ": если член имеет ключевое слово-модификатор "}, {"type": "string", "attributes": {"bold": true}, "string": "static"}, {"type": "string", "attributes": {}, "string": ", то он существует в классе, а не в экземплярах объектов. Вы можете добавить статический член в класс "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": ", как показано в примере 3."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 3. Добавление статического члена в класс:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "class"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": " {\n"}, {"type": "string", "attributes": {"bold": true}, "string": "static"}, {"type": "string", "attributes": {}, "string": " label = «Exile»;\n}"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {}, "string": "Тогда поле будет доступно только через имя класса, "}, {"type": "string", "attributes": {"bold": true}, "string": "Song.label"}, {"type": "string", "attributes": {}, "string": ". В отличие от Java, экземпляры JavaScript не хранят ссылку на общую статическую переменную. Обратите внимание, что можно иметь статическое приватное поле со статической #"}, {"type": "string", "attributes": {"bold": true}, "string": "label"}, {"type": "string", "attributes": {}, "string": "; то есть приватное статическое поле."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Индексы совпадения регулярных выражений"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Regex "}, {"type": "string", "attributes": {"bold": true}, "string": "match"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-regexp-match-indices"}, "string": "был обновлен"}, {"type": "string", "attributes": {}, "string": ", чтобы включать больше информации о группах соответствия. По соображениям производительности эта информация включается только в том случае, если к регулярному выражению добавлен флаг "}, {"type": "string", "attributes": {"bold": true}, "string": "/d"}, {"type": "string", "attributes": {}, "string": ". (Более подробное описание значения "}, {"type": "string", "attributes": {"bold": true}, "string": "/d"}, {"type": "string", "attributes": {}, "string": " regex см. в "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-regexp-match-indices"}, "string": "RegExp Match Indices for ECMAScript"}, {"type": "string", "attributes": {}, "string": ")."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "В принципе, использование флага "}, {"type": "string", "attributes": {"bold": true}, "string": "/d"}, {"type": "string", "attributes": {}, "string": " заставляет механизм regex включать начало и конец всех совпадающих подстрок. Когда флаг присутствует, свойство "}, {"type": "string", "attributes": {"bold": true}, "string": "indices "}, {"type": "string", "attributes": {}, "string": "в результатах "}, {"type": "string", "attributes": {"bold": true}, "string": "exec "}, {"type": "string", "attributes": {}, "string": "будет содержать двумерный массив, где первое измерение представляет совпадение, а второе - начало и конец совпадения."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "В случае именованных групп в индексах будет присутствовать член под названием "}, {"type": "string", "attributes": {"bold": true}, "string": "groups"}, {"type": "string", "attributes": {}, "string": ", первое измерение которого содержит имя группы. Рассмотрим пример 4, который взят "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-regexp-match-indices#examples"}, "string": "отсюда"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 4. Индексы групп Regex:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "const"}, {"type": "string", "attributes": {}, "string": " re1 = /a+(?<Z>z)?/d;\n\n"}, {"type": "string", "attributes": {"italic": true}, "string": "// block 1"}, {"type": "string", "attributes": {}, "string": "\n"}, {"type": "string", "attributes": {"bold": true}, "string": "const"}, {"type": "string", "attributes": {}, "string": " s1 = «xaaaz»;\n"}, {"type": "string", "attributes": {"bold": true}, "string": "const"}, {"type": "string", "attributes": {}, "string": " m1 = re1."}, {"type": "string", "attributes": {"bold": true}, "string": "exec"}, {"type": "string", "attributes": {}, "string": "(s1);\nm1.indices[0][0] === 1;\nm1.indices[0][1] === 5;\ns1.slice(...m1.indices[0]) === «aaaz»;\n\n"}, {"type": "string", "attributes": {"italic": true}, "string": "// block 2"}, {"type": "string", "attributes": {}, "string": "\nm1.indices[1][0] === 4;\nm1.indices[1][1] === 5;\ns1.slice(...m1.indices[1]) === «z»;\n\n"}, {"type": "string", "attributes": {"italic": true}, "string": "// block 3"}, {"type": "string", "attributes": {}, "string": "\nm1.indices.groups[«Z» ][0] === 4;\nm1.indices.groups[«Z» ][1] === 5;\ns1.slice(...m1.indices.groups[«Z» ]) === «z»;\n\n"}, {"type": "string", "attributes": {"italic": true}, "string": "// block 4"}, {"type": "string", "attributes": {}, "string": "\n"}, {"type": "string", "attributes": {"bold": true}, "string": "const"}, {"type": "string", "attributes": {}, "string": " m2 = re1."}, {"type": "string", "attributes": {"bold": true}, "string": "exec"}, {"type": "string", "attributes": {}, "string": "(«xaaay» );\nm2.indices[1] === "}, {"type": "string", "attributes": {"bold": true}, "string": "undefined"}, {"type": "string", "attributes": {}, "string": ";\nm2.indices.groups[«Z» ] === "}, {"type": "string", "attributes": {"bold": true}, "string": "undefined"}, {"type": "string", "attributes": {}, "string": ";"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {}, "string": "В примере 4 мы создаем регулярное выражение, которое соответствует символу "}, {"type": "string", "attributes": {"bold": true}, "string": "a"}, {"type": "string", "attributes": {}, "string": " один или более раз, а затем именованную группу соответствия (с именем "}, {"type": "string", "attributes": {"bold": true}, "string": "Z"}, {"type": "string", "attributes": {}, "string": "), которая соответствует символу "}, {"type": "string", "attributes": {"bold": true}, "string": "z "}, {"type": "string", "attributes": {}, "string": "ноль или более раз."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"italic": true}, "string": "В первом блоке"}, {"type": "string", "attributes": {}, "string": " кода демонстрируется, что "}, {"type": "string", "attributes": {"bold": true}, "string": "m1.indices[0][0]"}, {"type": "string", "attributes": {}, "string": " и "}, {"type": "string", "attributes": {"bold": true}, "string": "m1.indices[0][1]"}, {"type": "string", "attributes": {}, "string": " содержат 1 и 5 соответственно. Это потому, что первым совпадением для regex является строка от первого "}, {"type": "string", "attributes": {"bold": true}, "string": "a"}, {"type": "string", "attributes": {}, "string": " до строки, заканчивающейся на "}, {"type": "string", "attributes": {"bold": true}, "string": "z"}, {"type": "string", "attributes": {}, "string": ". "}, {"type": "string", "attributes": {"italic": true}, "string": "Блок 2"}, {"type": "string", "attributes": {}, "string": " показывает то же самое для символа "}, {"type": "string", "attributes": {"bold": true}, "string": "z"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"italic": true}, "string": "В блоке 3"}, {"type": "string", "attributes": {}, "string": " показан доступ к первому измерению с именованной группой через "}, {"type": "string", "attributes": {"bold": true}, "string": "m1.indices.groups"}, {"type": "string", "attributes": {}, "string": ". Есть одна совпадающая группа - последний символ "}, {"type": "string", "attributes": {"bold": true}, "string": "z"}, {"type": "string", "attributes": {}, "string": ", и она имеет начало 4 и конец 5."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Наконец, "}, {"type": "string", "attributes": {"italic": true}, "string": "блок 4"}, {"type": "string", "attributes": {}, "string": " демонстрирует, что несопоставленные индексы и группы возвращают неопределенный результат."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "В итоге, если вам нужен доступ к деталям сопоставления групп в строке, теперь вы можете использовать функцию "}, {"type": "string", "attributes": {"bold": true}, "string": "regex match indices"}, {"type": "string", "attributes": {}, "string": " для их получения."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Высокоуровневое ожидание"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Спецификация ECMAScript теперь включает возможность упаковывать асинхронные модули. Когда вы импортируете модуль, обернутый в "}, {"type": "string", "attributes": {"bold": true}, "string": "await"}, {"type": "string", "attributes": {}, "string": ", включающий модуль не будет выполняться, пока не будут выполнены все "}, {"type": "string", "attributes": {"bold": true}, "string": "await"}, {"type": "string", "attributes": {}, "string": ". Это позволяет избежать потенциальных ситуаций гонки при работе с взаимозависимыми вызовами асинхронных модулей. Подробности см. в "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-top-level-await"}, "string": "предложении высокоуровневого "}, {"type": "string", "attributes": {"bold": true, "href": "https://github.com/tc39/proposal-top-level-await"}, "string": "await"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"italic": true}, "string": "В примере 5"}, {"type": "string", "attributes": {}, "string": " приведен пример, заимствованный "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-top-level-await#solution-top-level-await"}, "string": "отсюда"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 5. Высокоуровневый await"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"italic": true}, "string": "// awaiting.mjs"}, {"type": "string", "attributes": {}, "string": "\n"}, {"type": "string", "attributes": {"bold": true}, "string": "import"}, {"type": "string", "attributes": {}, "string": " { process } "}, {"type": "string", "attributes": {"bold": true}, "string": "from"}, {"type": "string", "attributes": {}, "string": " «./some-module.mjs»;\n"}, {"type": "string", "attributes": {"bold": true}, "string": "const"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "dynamic"}, {"type": "string", "attributes": {}, "string": " = "}, {"type": "string", "attributes": {"bold": true}, "string": "import"}, {"type": "string", "attributes": {}, "string": "(computedModuleSpecifier);\n"}, {"type": "string", "attributes": {"bold": true}, "string": "const"}, {"type": "string", "attributes": {}, "string": " data = fetch(url);\n"}, {"type": "string", "attributes": {"bold": true}, "string": "export"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "const"}, {"type": "string", "attributes": {}, "string": " output = process((await "}, {"type": "string", "attributes": {"bold": true}, "string": "dynamic"}, {"type": "string", "attributes": {}, "string": ")."}, {"type": "string", "attributes": {"bold": true}, "string": "default"}, {"type": "string", "attributes": {}, "string": ", await data);\n"}, {"type": "string", "attributes": {"italic": true}, "string": "// usage.mjs"}, {"type": "string", "attributes": {}, "string": "\n"}, {"type": "string", "attributes": {"bold": true}, "string": "import"}, {"type": "string", "attributes": {}, "string": " { output } "}, {"type": "string", "attributes": {"bold": true}, "string": "from"}, {"type": "string", "attributes": {}, "string": " «./awaiting.mjs»;\n"}, {"type": "string", "attributes": {"bold": true}, "string": "export"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "function"}, {"type": "string", "attributes": {}, "string": " outputPlusValue(value) { "}, {"type": "string", "attributes": {"bold": true}, "string": "return"}, {"type": "string", "attributes": {}, "string": " output + value }\n\nconsole.log(outputPlusValue(100));\nsetTimeout(() => console.log(outputPlusValue(100), 1000);"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {}, "string": "Обратите внимание в файле "}, {"type": "string", "attributes": {"bold": true}, "string": "awaiting.mjs"}, {"type": "string", "attributes": {}, "string": " на ключевое слово "}, {"type": "string", "attributes": {"bold": true}, "string": "await"}, {"type": "string", "attributes": {}, "string": " перед использованием зависимых модулей "}, {"type": "string", "attributes": {"bold": true}, "string": "dynamic"}, {"type": "string", "attributes": {}, "string": " и "}, {"type": "string", "attributes": {"bold": true}, "string": "data"}, {"type": "string", "attributes": {}, "string": ". Это означает, что когда "}, {"type": "string", "attributes": {"bold": true}, "string": "usage.mjs"}, {"type": "string", "attributes": {}, "string": " импортирует "}, {"type": "string", "attributes": {"bold": true}, "string": "awaiting.mjs"}, {"type": "string", "attributes": {}, "string": ", "}, {"type": "string", "attributes": {"bold": true}, "string": "usage.mjs"}, {"type": "string", "attributes": {}, "string": " не будет выполняться, пока зависимости "}, {"type": "string", "attributes": {"bold": true}, "string": "awaiting.mjs"}, {"type": "string", "attributes": {}, "string": " не закончат загрузку."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Новые эргономичные проверки для приватных полей"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Как разработчики, мы хотим код, который удобен - для этого были сделаны "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-private-fields-in-in"}, "string": "эргономичные приватные поля"}, {"type": "string", "attributes": {}, "string": ". Эта новая возможность позволяет нам проверять наличие приватного поля у класса, не прибегая к обработке исключений."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"italic": true}, "string": "В примере 6"}, {"type": "string", "attributes": {}, "string": " показан этот новый, эргономичный способ проверки наличия приватного поля изнутри класса с помощью ключевого слова "}, {"type": "string", "attributes": {"bold": true}, "string": "in"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 6. Проверка существования приватного поля:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "class"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": " {\n#"}, {"type": "string", "attributes": {"italic": true}, "string": "artist;"}, {"type": "string", "attributes": {}, "string": "\ncheckField(){\n"}, {"type": "string", "attributes": {"bold": true}, "string": "return"}, {"type": "string", "attributes": {}, "string": " #"}, {"type": "string", "attributes": {"italic": true}, "string": "artist in this;"}, {"type": "string", "attributes": {}, "string": "\n}\n}\n"}, {"type": "string", "attributes": {"bold": true}, "string": "let"}, {"type": "string", "attributes": {}, "string": " foo = "}, {"type": "string", "attributes": {"bold": true}, "string": "new"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "Song"}, {"type": "string", "attributes": {}, "string": "();\nfoo.checkField(); "}, {"type": "string", "attributes": {"italic": true}, "string": "// true"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {"italic": true}, "string": "Пример 6"}, {"type": "string", "attributes": {}, "string": " является надуманным, но идея понятна. Когда вам понадобится проверить класс на наличие закрытого поля, вы можете использовать формат:"}, {"type": "string", "attributes": {"bold": true}, "string": "# fieldName in object"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Отрицательная индексация с помощью.at()"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Прошли времена "}, {"type": "string", "attributes": {"bold": true}, "string": "arr[arr.length -2]"}, {"type": "string", "attributes": {}, "string": ". "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-relative-indexing-method"}, "string": "Метод "}, {"type": "string", "attributes": {"bold": true, "href": "https://github.com/tc39/proposal-relative-indexing-method"}, "string": ".at"}, {"type": "string", "attributes": {}, "string": " для встроенных индексируемых элементов теперь поддерживает отрицательные индексы, как показано "}, {"type": "string", "attributes": {"italic": true}, "string": "в примере 7"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 7. Отрицательный индекс с помощью.at():"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "let"}, {"type": "string", "attributes": {}, "string": " foo = [1,2,3,4,5];\nfoo.at(3); "}, {"type": "string", "attributes": {"italic": true}, "string": "// == 3"}, {"type": "string", "attributes": {}, "string": "\nhasOwn"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {}, "string": "hasOwn"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-accessible-object-hasownproperty"}, "string": "Object.hasOwn"}, {"type": "string", "attributes": {}, "string": " - это улучшенная версия "}, {"type": "string", "attributes": {"bold": true}, "string": "Object.hasOwnProperty"}, {"type": "string", "attributes": {}, "string": ". Она работает в некоторых исключительных случаях, например, когда объект создается с помощью "}, {"type": "string", "attributes": {"bold": true}, "string": "Object.create(null)"}, {"type": "string", "attributes": {}, "string": ". Обратите внимание, что "}, {"type": "string", "attributes": {"bold": true}, "string": "hasOwn"}, {"type": "string", "attributes": {}, "string": " является статическим методом - он не существует для экземпляров."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 8. hasOwn() в действии:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "let"}, {"type": "string", "attributes": {}, "string": " foo = "}, {"type": "string", "attributes": {"bold": true}, "string": "Object"}, {"type": "string", "attributes": {}, "string": ".create("}, {"type": "string", "attributes": {"bold": true}, "string": "null"}, {"type": "string", "attributes": {}, "string": ");\nfoo.hasOwnProperty = "}, {"type": "string", "attributes": {"bold": true}, "string": "function"}, {"type": "string", "attributes": {}, "string": "(){};\n"}, {"type": "string", "attributes": {"bold": true}, "string": "Object"}, {"type": "string", "attributes": {}, "string": ".hasOwnProperty(foo, 'hasOwnProperty'); "}, {"type": "string", "attributes": {"italic": true}, "string": "// Error: Cannot convert object to primitive value"}, {"type": "string", "attributes": {}, "string": "\n"}, {"type": "string", "attributes": {"bold": true}, "string": "Object"}, {"type": "string", "attributes": {}, "string": ".hasOwn(foo, 'hasOwnProperty'); "}, {"type": "string", "attributes": {"italic": true}, "string": "// true"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {"italic": true}, "string": "В примере 8"}, {"type": "string", "attributes": {}, "string": " показано, что вы можете использовать "}, {"type": "string", "attributes": {"bold": true}, "string": "Object.hasOwn"}, {"type": "string", "attributes": {}, "string": " для экземпляра "}, {"type": "string", "attributes": {"bold": true}, "string": "foo"}, {"type": "string", "attributes": {}, "string": ", созданного с помощью "}, {"type": "string", "attributes": {"bold": true}, "string": "Object.create(null)"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Статический блок класса"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Вот шанс для разработчиков Java сказать: «О, у нас это было с 90-х годов». ES 2022 вводит в JavaScript "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-class-static-block"}, "string": "статические блоки инициализации"}, {"type": "string", "attributes": {}, "string": ". По сути, вы можете использовать ключевое слово "}, {"type": "string", "attributes": {"bold": true}, "string": "static "}, {"type": "string", "attributes": {}, "string": "в блоке кода, который запускается при загрузке класса, и он будет иметь доступ к статическим членам."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"italic": true}, "string": "В примере 9"}, {"type": "string", "attributes": {}, "string": " приведен простой пример использования статического блока для инициализации статического значения."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 9. Статический блок:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "class"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "Foo"}, {"type": "string", "attributes": {}, "string": " {\n"}, {"type": "string", "attributes": {"bold": true}, "string": "static"}, {"type": "string", "attributes": {}, "string": " bar;\n"}, {"type": "string", "attributes": {"bold": true}, "string": "static"}, {"type": "string", "attributes": {}, "string": " {\n"}, {"type": "string", "attributes": {"bold": true}, "string": "this"}, {"type": "string", "attributes": {}, "string": ".bar = “test”;\n}\n}"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {}, "string": "Причина ошибки"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "И последнее, но не менее важное: класс "}, {"type": "string", "attributes": {"bold": true}, "string": "Error "}, {"type": "string", "attributes": {}, "string": "теперь включает в себя "}, {"type": "string", "attributes": {"href": "https://github.com/tc39/proposal-error-cause"}, "string": "поддержку причин"}, {"type": "string", "attributes": {}, "string": ". Это позволяет использовать в цепочках ошибок стековые трассировки, подобные Java. Конструктор ошибок теперь позволяет использовать объект "}, {"type": "string", "attributes": {"bold": true}, "string": "options"}, {"type": "string", "attributes": {}, "string": ", который включает поле "}, {"type": "string", "attributes": {"bold": true}, "string": "cause"}, {"type": "string", "attributes": {}, "string": ", как показано "}, {"type": "string", "attributes": {"italic": true}, "string": "в примере 10"}, {"type": "string", "attributes": {}, "string": "."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Пример 10. Причина ошибки:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "throw"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "new"}, {"type": "string", "attributes": {}, "string": " "}, {"type": "string", "attributes": {"bold": true}, "string": "Error"}, {"type": "string", "attributes": {}, "string": "('Error message', { cause: errorCause });"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {}, "string": "Заключение"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Понравилась статья? Тогда ставьте лайки, пишите комментарии, делитесь ею с друзьями, а также подписывайтесь на нас тут и на других площадках (ссылка в шапке профиля)."}], "attributes": []}], "selectedRange": [180, 180]}
Комментарии 0