Перейти к основному содержимому

ES2015, ES2016 и далее

· 8 мин. чтения
команда V8, энтузиасты ECMAScript

Команда V8 придает большое значение эволюции JavaScript в все более выразительный и четко определенный язык, который упрощает написание быстрых, безопасных и правильных веб-приложений. В июне 2015 года комитетом стандартизации TC39 была ратифицирована спецификация ES2015, что стало крупнейшим обновлением языка JavaScript. Новые функции включают классы, стрелочные функции, обещания (promises), итераторы/генераторы, прокси, общеизвестные символы, а также дополнительный синтаксический сахар. TC39 также ускорил процесс выпуска новых спецификаций и в феврале 2016 года выпустил кандидат на ES2016, который будет ратифицирован этим летом. Хотя это обновление не такое обширное, как ES2015 из-за более короткого цикла выпуска, ES2016 примечательно вводит оператор возведения в степень и Array.prototype.includes.

Сегодня мы достигли важного рубежа: V8 поддерживает ES2015 и ES2016. Вы можете использовать новые языковые возможности уже сегодня в Chrome Canary, а они будут включены по умолчанию в Chrome 52.

Учитывая природу эволюционирующей спецификации, различия между различными типами тестов на соответствие и сложность поддержания веб-совместимости, может быть трудно определить, когда определенная версия ECMAScript считается полностью поддерживаемой движком JavaScript. Читайте далее, чтобы узнать, почему поддержка спецификаций более детализирована, чем версия, почему правильные хвостовые вызовы все еще обсуждаются и какие оговорки остаются в силе.

Эволюционирующая спецификация

Когда TC39 решил публиковать более частые обновления спецификации JavaScript, самая актуальная версия языка стала основной, черновой версией. Хотя версии спецификации ECMAScript все еще выпускаются ежегодно и ратифицируются, V8 реализует комбинацию наиболее недавно ратифицированной версии (например, ES2015), определенные функции, которые достаточно близки к стандартизации, чтобы их можно было безопасно реализовать (например, оператор возведения в степень и Array.prototype.includes() из кандидатских черновиков ES2016), а также набор исправлений ошибок и поправок веб-совместимости из более поздних черновиков. Часть обоснования для такого подхода заключается в том, что реализации языков в браузерах должны соответствовать спецификации, даже если это спецификация, которая требует обновления. Фактически, процесс реализации ратифицированной версии спецификации часто выявляет многие исправления и уточнения, составляющие следующую версию спецификации.

Текущие части меняющейся спецификации ECMAScript, которые поставляются

Например, при реализации флага sticky для RegExp ES2015 команда V8 обнаружила, что семантика спецификации ES2015 ломала многие существующие сайты (включая все сайты, использующие версии 2.x.x популярной библиотеки XRegExp). Поскольку совместимость является краеугольным камнем веба, инженеры из V8 и Safari JavaScriptCore предложили поправку к спецификации RegExp, чтобы исправить проблему, которую согласовал TC39. Поправка не появится в ратифицированной версии до ES2017, но она по-прежнему является частью языка ECMAScript, и мы реализовали ее для поставки флага sticky для RegExp.

Постоянное уточнение спецификации языка и тот факт, что каждая версия (включая еще не ратифицированный черновик) заменяет, исправляет и уточняет предыдущие версии, делает сложным понимание нюансов поддержки ES2015 и ES2016. Хотя это невозможно выразить кратко, возможно, наиболее точно сказать, что V8 поддерживает соответствие с «постоянно обновляемым черновым будущим стандартом ECMAScript»!

Измерение соответствия

В попытке разобраться с этой сложностью спецификации существует множество способов измерения совместимости JavaScript-движка с стандартом ECMAScript. Команда V8, а также другие производители браузеров, используют набор тестов Test262 в качестве золотого стандарта соответствия постоянно поддерживаемому черновику будущих стандартов ECMAScript. Этот набор тестов постоянно обновляется в соответствии со спецификацией и предоставляет 16 000 отдельных функциональных тестов для всех функций и крайних случаев, из которых состоит совместимая и корректная реализация JavaScript. В настоящее время V8 успешно проходит около 98% тестов test262, а оставшиеся 2% — это несколько крайних случаев и будущих ES-функций, которые еще не готовы к выпуску.

Поскольку трудно бегло просмотреть огромное количество тестов test262, существуют и другие тесты соответствия, такие как таблица совместимости Kangax. Таблица Kangax облегчает проверку того, была ли определенная функция (например, стрелочные функции) реализована в конкретном движке, однако она не тестирует все крайние случаи совместимости, как это делает test262. В настоящее время Chrome Canary набирает 98% в таблице Kangax для ES2015 и 100% в разделах Kangax, соответствующих ES2016 (например, разделы «2016 features» и «2016 misc» во вкладке ESnext).

Оставшиеся 2% тестов таблицы Kangax для ES2015 правильные хвостовые вызовы, функция, которая была реализована в V8, но намеренно отключена в Chrome Canary из-за нерешенных проблем с опытом разработки, описанных ниже. С включенным флагом «Экспериментальные функции JavaScript», который насильно включает эту функцию, Chrome Canary набирает 100% по всей таблице Kangax для ES2015.

Правильные хвостовые вызовы

Правильные хвостовые вызовы были реализованы, но еще не выпущены, поскольку изменение этой функции в настоящее время обсуждается в TC39. ES2015 определяет, что строгие вызовы функций в хвостовой позиции не должны вызывать переполнение стека. Хотя это полезная гарантия для определенных шаблонов программирования, текущая семантика имеет две проблемы. Во-первых, поскольку устранение хвостовых вызовов происходит неявно, программистам может быть трудно определить, какие функции действительно находятся в хвостовой позиции. Это означает, что разработчики могут не обнаружить неправильно расположенные попытки хвостовых вызовов в своих программах до тех пор, пока они не вызовут переполнение стека. Во-вторых, реализация правильных хвостовых вызовов требует исключения кадров вызова хвоста из стека, что приводит к потере информации о потоке выполнения. Это, в свою очередь, имеет два следствия:

  1. Это усложняет процесс отладки, так как трудно понять, как выполнение достигло определенной точки, поскольку стек содержит разрывы, и
  2. error.stack содержит меньше информации о потоке выполнения, что может нарушить работу программ телеметрии, которые собирают и анализируют ошибки на стороне клиента.

Реализация теневого стека может улучшить читаемость стека вызовов, однако команды V8 и DevTools считают, что отладка наиболее проста, надежна и точна, когда стек, отображаемый во время отладки, полностью детерминирован и всегда соответствует истинному состоянию стека виртуальной машины. Кроме того, теневой стек слишком дорог с точки зрения производительности, чтобы включать его постоянно.

По этим причинам команда V8 решительно поддерживает обозначение правильных хвостовых вызовов с помощью специального синтаксиса. Существует ожидающее предложение TC39, называемое синтаксическими хвостовыми вызовами, чтобы определить это поведение, содействуемое членами комитета от Mozilla и Microsoft. Мы реализовали и подготовили правильные хвостовые вызовы, как указано в ES2015, и начали реализовывать синтаксические хвостовые вызовы, как указано в новом предложении. Команда V8 планирует решить данную проблему на следующем собрании TC39 до выпуска по умолчанию неявных правильных хвостовых вызовов или синтаксических хвостовых вызовов. Вы можете протестировать каждую версию, используя флаги V8 --harmony-tailcalls и --harmony-explicit-tailcalls. Обновление: Эти флаги были удалены.

Модули

Одно из самых захватывающих обещаний ES2015 — поддержка модулей JavaScript для организации и разделения различных частей приложения на пространства имен. ES2015 специфицирует директивы import и export для модулей, но не определяет, как модули загружаются в программу JavaScript. В браузере поведение загрузки недавно было специфицировано через <script type="module">. Хотя требуется дополнительная работа по стандартизации для уточнения продвинутых API загрузки модулей, поддержка Chromium для тегов сценариев модулей уже находится в разработке. Вы можете следить за выполнением работ по ошибке запуска и узнать больше об экспериментальных идеях API загрузчика в репозитории whatwg/loader.

ESnext и далее

В будущем разработчики могут ожидать, что обновления ECMAScript будут выходить в виде более мелких и частых релизов с сокращенными циклами реализации. Команда V8 уже работает над внедрением предстоящих функций, таких как ключевые слова async/await, методы Object.values / Object.entries, String.prototype.{padStart,padEnd} и RegExp lookbehind в среду выполнения. Возвращайтесь для получения дополнительных обновлений о нашем прогрессе в реализации ESnext и оптимизации производительности существующих функций ES2015 и ES2016+.

Мы стремимся продолжать развивать JavaScript, находя правильный баланс между ранней реализацией новых функций, обеспечением совместимости и стабильности существующей сети, а также предоставлением обратной связи TC39 по вопросам проектирования. Мы с нетерпением ждем, какие невероятные возможности разработчики создадут с этими новыми функциями.