Что но­во­го в JavaScript 2019

Перевод «What’s New in JavaScript for 2019»

Перевод Алёна Батицкая

Редактура Вадим Макеев

На протяжении последних лет JavaScript развивался и получал новые фичи. Если вам любопытно, чего ждать от новой версии JavaScript, то этот пост для вас!

Перед тем, как мы поговорим о новых возможностях, важно понять как новые идеи становятся частью языка JavaScript.

Процесс для новых возможностей JavaScriptСкопировать ссылку

Если коротко, то спецификация языка, которая управляет JavaScript, называется ECMAScript. Группа Ecma International, которая рассматривает и принимает изменения в спецификацию языка, называется Технический комитет 39 или TC39. Изменения в спецификацию ECMAScript проходят через стандартизированный процесс, включая стадии становления.

  • Этап 0: идеи
  • Этап 1: официальное предложение
  • Этап 2: черновики
  • Этап 3: кандидаты
  • Этап 4: одобренные

До тех пор, пока нововведение не достигнет 4 этапа, нет никаких гарантий, что оно станет частью спецификации ECMAScript. Тем не менее, некоторые JavaScript-движки, такие, как V8 (используется в Сhrome and Node.js) и SpiderMonkey от Firefox, могут добавить поддержку предложенных возможностей до того, как они перешли на этап 4. Так разработчики могут протестировать их и дать фидбэк.

Текущие кандидаты в ECMAScript2019Скопировать ссылку

В момент написания этой статьи уже существует список предложений TC39, которые находятся на 4 этапе. И тем не менее есть несколько кандидатов на 3 этапе.

Дисклеймер: поскольку есть несколько кандидатов на этапе 3, финальный вариант ECMAScript2019 может не включать в себя все перечисленные предложения. По факту некоторые из этих предложений находятся на рассмотрении годами. Кроме того, реализации новых возможностей могут выглядеть или вести себя не так, как описано в текущих кандидатах.

Изменения в классах JavaScriptСкопировать ссылку

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

class Truck extends Automobile {
    model = 'Очень мощный'; // Объявление публичного поля
    #numberOfSeats = 5; // Объявление приватного поля
    #isCrewCab = true;
    static #name = 'Грузовик'; // Статическое приватное поле

    // Статичный метод
    static formattedName() {
        // Обратите внимание, что имя класса Truck используется
        // вместо this чтобы получить доступ к статическому полю
        return `Это автомобиль ${ Truck.#name }.`;
    }

    constructor( model, seats = 2 ) {
        super();
        this.seats = seats;
    }

    // Приватный метод
    #getBodyType() {
        return this.#isCrewCab ?
            'Двойная кабина' : 'Стандартная кабина';
    }

    bodyType() {
        return `${ this.#numberOfSeats }-passenger ${ this.model } ${ this.#getBodyType() }`;
    }

    get seats() { return this.#numberOfSeats; }
    set seats( value ) {
        if ( value >= 1 && value < 7 ) {
            this.#numberOfSeats = value;
            this.#isCrewCab = value > 3;
        }
    }
}

Лично мне не очень нравится синтаксис # для приватных полей и методов. Я бы предпочёл чтобы в спецификации JavaScript использовалось ключевое слово private для этих целей по аналогии с другими языками.

Строковые методы trimStart() и trimEnd()Скопировать ссылку

У типа данных String существует метод trim(), с помощью которого можно удалить пробелы с обоих концов строки. Предложено ввести методы trimStart() и trimEnd(), которые дадут больше контроля над удалением пробелов.

const one = '      Привет и позвольте ';
const two = 'нам начать.        ';
console.log( one.trimStart() + two.trimEnd() )
// "Привет и позвольте нам начать."

Интересный факт: эта возможность языка уже реализована во многих JavaScript-движках. Один из случаев когда браузеры помогают развивать язык.

Большие числа с BigIntСкопировать ссылку

Мы видим примитив BigInt для целых чисел, превышающих текущее максимальное значение 253. BigInt может быть объявлен несколькими различными способами.

// Референс
const theBiggestIntegerToday = Number.MAX_SAFE_INTEGER;
// 9007199254740991

// Используем синтаксис 'n' для объявления BigInt
const ABiggerInteger = 9100000000000001n;

// Используем конструктор BigInt()
const EvenBigger = BigInt( 9100000000000002 );
// 9100000000000002n

// Используем конструктор BigInt() со строкой
const SuchBigWow = BigInt( '9100000000000003' );
// 9100000000000003n

Узнайте больше о вариантах использования и фишках BigInt.

Одномерные массивы с flat() и flatMap()Скопировать ссылку

Если вы изучали функциональное программирование, то вы точно узнаете flat() и flatMap(). flat() принимает массив значений, который может состоять в том числе из других массивов, и возвращает новый одномерный массив.

const nestedArraysOhMy = ['a', ['b', 'c'], ['d', ['e', 'f']]];
// .flat() принимает необязательный аргумент глубины
const ahhThatsBetter = nestedArraysOhMy.flat(2);
console.log( ahhThatsBetter );
// ['a', 'b', 'c', 'd', 'e', 'f']

flatMap() похож на map(), но колбэк может вернуть массив и в результате получится плоский одномерный массив вместо вложенных массивов.

const scattered = ['мой любимый', 'бутерброд', 'это', 'сэндвич с курицей'];

// Обычный map() вернёт вложенные массивы
const huh = scattered.map(chunk => chunk.split(' '));
console.log(huh);
// [['мой', 'любимый'], ['бутерброд'], ['это'], ['сэндвич', 'с', 'курицей']]

// flatMap() объединяет возвращаемые массивы
const better = scattered.flatMap( chunk => chunk.split( ' ' ) );
console.log(better);
// ['мой', 'любимый', 'бутерброд', 'это', 'сэндвич', 'с', 'курицей']

Другие предложения-кандидаты в ES2019Скопировать ссылку

Ниже представлен список дополнительных кандидатов, которые находятся на 3 этапе в момент написания статьи.

Когда ожидать ES2019Скопировать ссылку

В последние годы TC39 выпускает обновлённую спецификацию ECMA-262 языка ECMAScript в июне. Всё говорит о том, что и ES2019 мы увидим в июне.

Попробуйте новинки ES2019 уже сегодняСкопировать ссылку

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

Потестируйте в последней версии Node.jsСкопировать ссылку

Node.js использует движок Chrome V8. Некоторые кандидаты могут быть использованы в Node.js потому что V8 уже поддерживает их (например, Array.prototype.flat и String.prototype.trimEnd).

Вы можете включить другие фичи языка при помощи --harmony-{feature-flag} в параметрах командной строки. Чтобы проверить, какие флаги поддерживает ваша версия Node.js, используйте опцию --v8-options для получения списка. Некоторые кандидаты будут помечены «in progress» (прим. переводчика: в процессе).

MacOS или Linux:

node --v8-options | grep "in progress"

Windows:

node --v8-options | find "in progress"

Например, чтобы запустить приложение Node.js с поддержкой строковой декларации и статических методов, вы можете использовать следующие опции CLI.

node --harmony-class-fields --harmony-static-fields index.js

Тестируйте с Babel 7.0+Скопировать ссылку

Babel это утилита JavaScript, которая позволяет вам использовать последние возможности языка, даже если они ещё не поддерживаются всеми браузерами и окружающими средами. Вы пишите «современный» JavaScript, а Babel переводит ваш код в синтаксис, который поддерживается старыми движками.

Babel поддерживает экспериментальные возможности языка при помощи плагинов. Babel публикует список поддерживаемых возможностей ECMAScript в своём официальном репозитории.

Что ещё почитать о JavaScript и ES NextСкопировать ссылку

Хотите знать больше о JavaScript? Посетите некоторые из этих полезных ресурсов.

Если вам будет интересно, то вы можете почитать предыдущие версии ECMAScript, например, ES2015, ES2016 и ES2017.