[Перевод] 4 революционных возможности JavaScript из будущего

JavaScript, с момента выхода стандарта ECMAScript 6 (ES6), быстро и динамично развивается. Благодаря тому, что теперь новые версии стандарта ECMA-262 выходят ежегодно, и благодаря титаническому труду всех производителей браузеров, JS стал одним из самых популярных языков программирования в мире.

Недавно я писал о новых возможностях, которые появились в стандарте ES2020. Хотя некоторые из этих возможностей и весьма интересны, среди них нет таких, которые достойны называться «революционными». Это вполне можно понять, учитывая то, что в наши дни спецификация JS обновляется достаточно часто. Получается, что у тех, кто работает над стандартом, просто меньше возможностей для постоянного внедрения в язык чего-то особенного, вроде ES6-модулей или стрелочных функций.

a79ouf_0elh8urjkhe44ftmwa2i.jpeg

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

Декораторы (decorators)


Начнём мы с возможности, которую, вероятно, чаще всего просят включить в язык, и вокруг которой поднято довольно много шума. Пару лет назад о ней писали буквально повсюду. Речь идёт о декораторах.

Возможно, вы уже знакомы с декораторами. Особенно — если вы пишете на TypeScript. Это, в сущности, концепция метапрограммирования, нацеленная на то, чтобы дать разработчику возможность «внедрять» собственный функционал в классы, в их отдельные поля и методы, в итоге делая классы программируемыми.

Взгляните на следующий пример:

function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }
  greet() {
    return "Hello, " + this.greeting;
  }
}


Тут я решил действовать осторожно и привёл пример использования TypeScript-декораторов. Сделал я это, преимущественно, для того, чтобы показать общую идею. В вышеприведённом фрагменте кода мы создали декоратор sealed и применили его к классу Greeter. Как несложно заметить, декоратор — это просто функция, у которой есть доступ к конструктору класса, к которому она применена (это — цель). Мы используем ссылку на конструктор, а так же — метод Object.seal() для того чтобы сделать класс нерасширяемым.

Для того чтобы применить декоратор к классу, мы записываем имя декоратора со значком @ сразу перед объявлением класса. В результате получается, что перед объявлением класса появляется конструкция вида @[name], что в нашем случае выглядит как @sealed.

Проверить работоспособность декоратора можно, скомпилировав этот TS-код с включённой опцией experimentalDecorators и попробовав изменить прототип класса:

Greeter.prototype.test = "test"; // ERROR


В результате, теперь у вас должно появиться общее понимание того, зачем вообще нужны декораторы. Но мне хотелось бы затронуть тут один непростой вопрос. Он касается того, в каком состоянии сейчас находится согласование предложения по декораторам.

Я решил использовать TypeScript для демонстрации декораторов не без причины. Дело в том, что предложение, касающееся внедрения декораторов в JavaScript, появилось уже несколько лет назад. И оно сейчас «всего лишь» на 2 стадии согласования из 4. И в синтаксис, и в возможности декораторов из этого предложения постоянно вносят изменения. Но это не останавливает JS-сообщество от использования данной концепции. Для того чтобы в этом убедиться, достаточно взглянуть на огромные опенсорсные проекты вроде TypeScript или Angular v2+.

Правда, всё это, с течением времени, и по мере того, как предложение развивается, ведёт к проблеме, связанной с несовместимостью спецификаций. А именно, спецификация декораторов сильно развилась с момента появления соответствующего предложения, но многие проекты всё ещё её не реализовали. Пример на TypeScript, показанный выше, это демонстрация реализации более старой версии предложения. То же самое можно сказать и об Angular, и даже о Babel (хотя, в случае с Babel, можно говорить о том, что сейчас ведётся работа над реализацией более новой версии этой спецификации). В целом же, более новая версия предложения, в которой используется ключевое слово decorator и синтаксис, пригодный для компоновки, пока ещё не нашла хоть какого-то заметного применения.

В итоге можно сказать, что у декораторов есть потенциальная возможность изменить то, как мы пишем код. И эти изменения уже показывают себя, даже учитывая то, что внедрение декораторов находится на ранней стадии. Правда, учитывая текущее положение дел, декораторы лишь фрагментируют сообщество, и я полагаю, что они пока ещё не готовы к по-настоящему серьёзному использованию. Я посоветовал бы тем, кому декораторы интересны, немного подождать перед их внедрением в продакшн. Моя рекомендация, правда, не относится к тем, кто использует фреймворки, в которых применяются декораторы (вроде Angular).

Области (realms)


Теперь давайте немного сбавим обороты и поговорим об одной возможности, не такой сложной, как декораторы. Речь идёт об областях.

Возможно, вы уже бывали в ситуациях, когда вам нужно запустить собственный код, или код стороннего разработчика, но при этом сделать это так, чтобы этот код не повлиял бы на глобальное окружение. Многие библиотеки, в особенности — браузерные, работают через глобальный объект window. В результате они могут друг другу мешать в том случае, если в проекте используется слишком много неконтролируемых разработчиком библиотек. Это может приводить к ошибкам.

Сейчас решение этой проблемы в браузере заключается в использовании элементов