Моя серия заметок ES6 in Depth, состоящая из 24 записей, описывает большинство синтаксических изменений и нововведений в ES6. В этой публикации я подведу итог всего изложенного в предыдущих статьях, чтобы дать возможность посмотреть еще раз на всё вместе. Также я добавил ссылки на мой блог, чтобы в случае необходимости сразу же можно было посмотреть подробнее.



Я слышал, вы любите маркированные списки, так что вот вам статья со списком, который состоит из нескольких сотен элементов.

Для начала приведу оглавление, чтобы было понятно, о чем пойдет речь. Очевидно, что оглавление – это также ненумерованный список. Обратите внимание: если хотите глубже вникнуть в эту тему, прочтите весь цикл статей и самостоятельно «поковыряйте» код ES6.

Содержание

? Введение
? Инструментарий
? Assignment Destructing
? Spread Operator и Rest Parameters
? Стрелочные функции
? Шаблонные строки
? Литералы объектов
? Классы
? Let и Const
? Символы
? Итераторы
? Генераторы
? Промайсы
? Maps
? WeakMaps
? Sets
? WeakSets
? Прокси
? Reflection
? Number
? Math
? Array
? Object
? Строки и Unicode
? Модули

Извините за такое длинное оглавление. Начинаем.

Введение

? ES6 (также известен как Harmony, es-next, ES2015) – последняя и окончательная спецификация языка.
? Окончательная спецификация ES6 была утверждена в июне 2015 года (следовательно, ES2015).
? Будущие версии языка будут называться согласно шаблону ES[YYYY], например ES2016 для ES7.
o Ежегодный релиз-цикл, необратимые изменения начинают действовать со следующего релиза.
o Так как ES6 появился раньше, чем это решение, большинство из нас всё еще называет его ES6.
o Начиная с ES2016 (ES7), мы должны использовать шаблон ES[YYYY], чтобы ссылаться на новые версии.
o Главная причина использования такого шаблона именования – оказание давления на производителей браузеров с целью как можно более быстрого внедрения последних обновлений.

Инструментарий

? Чтобы использовать ES6 сегодня, вам потребуется JavaScript-to-JavaScript транспайлер.
? Транспайлеры пришли и останутся, потому что:
o они предоставляют возможность компилировать код новой версии языка в код старой версии;
o мы будем транспайлить ES2016 и ES2017 в ES6 и т. д., когда браузерная поддержка станет лучше;
o нам потребуется улучшенный функционал source mapping;
o на сегодняшний день это самый надежный способ запускать ES6 код в продакшн (несмотря на то, что браузеры поддерживают ES5).
? У babel (транспайлера) есть киллер-фича: человекочитаемый вывод (human-readable output).
? Используйте babel, чтобы транспайлить ES6 в ES5 для статических сборок.
? Используйте babelify, чтобы внедрить babel в свой grunt, gulp или npm run процесс сборки.
? Используйте nodejs весии 4.x.x или выше – там есть весьма приличная поддержка ES6 (спасибо v8).
? Используйте babel-node с любой версией node.js – он будет транспайлить модули в ES5.
? В babel есть разрастающаяся экосистема, которая уже поддерживает ES2016 и некоторые плагины.
? Прочитайте A Brief History of ES6 Tooling.

Assignment Destructuring

? var {foo} = pony то же, что var foo = pony.foo.
? var {foo: baz} = pony то же, что var baz = pony.foo
? Можно задавать значения по умолчанию, var {foo='bar'} = baz вернет foo: 'bar', если baz.foo является undefined.
? Можно затащить сколько угодно свойств, под псевдонимами или без них:
o var {foo, bar: baz} = {foo: 0, bar: 1} даст foo: 0 и baz: 1.
? Можно пойти дальше: var {foo: {bar}} = { foo: { bar: 'baz' } } даст bar: 'baz'.
? Этому тоже можно назначить псевдоним: var {foo: {bar: deep}} = { foo: { bar: 'baz' } } даст вам deep: 'baz'.
? Свойства, которые не были найдены, по-прежнему возвращают undefined var {foo} = {}.
? Вложенные свойства, которые не были найдены, возвращают ошибку var {foo: {bar}} = {}.
? Это также работает для массивов, [a, b] = [0, 1] вернет a: 0 и b: 1.
? Можно пропускать элементы в массиве, [a,, b] = [0, 1, 2], получаем a: 0 и b: 2.
? Переменные можно менять местами, не прибегая к помощи третьей “aux” переменной, [a, b] = [b, a].
? Можно также использовать destructuring в параметрах функций:
o присваивание значений по умолчанию function foo (bar=2) {};
o эти значения могут также быть и объектами function foo (bar={ a: 1, b: 2 }) {};
o можно деструктурировать bar полностью: function foo ({ a=1, b=2 }) {};
o если ничего не было передано, по умолчанию получаем пустой массив: function foo ({ a=1, b=2 } = {}) {}.

Прочитайте ES6 JavaScript Destructuring in Depth.

Spread Operator и Rest Parameters

? Rest parameters – это как arguments, только лучше.
o сигнатура метода объявляется как function foo (...everything) {};
o everything – это массив со всеми параметрами, переданными в foo;
o можно присвоить имя нескольким параметрам перед ...everything, например: function foo (bar, ...rest) {};
o эти параметры будут исключены из ...rest;
o ...rest должен быть последним параметром в списке.
? Spread operator – это даже лучше, чем магия, он также обозначается при помощи … синтаксиса:
o отменяет необходимость apply при вызове методов, fn(...[1, 2, 3]) – то же, что fn(1, 2, 3);
o упрощенная конкатенация: [1, 2, ...[3, 4, 5], 6, 7];
o позволяет слепить массивоподобные элементы или коллекции в массивы [...document.querySelectorAll('img')];
o также полезен при destructing [a,, ...rest] = [1, 2, 3, 4, 5] возвращает a: 1 и rest: [3, 4, 5];
o делает new + .apply простым, new Date(...[2015, 31, 8]).
? Прочитайте ES6 Spread and Butter in Depth.

Стрелочные функции

? Лаконичный способ объявить функцию param => returnValue.
? Полезно при функциональном программировании, [1, 2].map(x => x * 2).
? Есть несколько разных способов использования (займет некоторое время, чтобы выработать привычку):
0 p1 => expr отлично подходит, если параметр один;
0 p1 => expr имеет неявный оператор return для выражения expr;
0 чтобы неявно вернуть объект, нужно обернуть его в круглые скобки () => ({ foo: 'bar' }), иначе получите ошибку;
0 круглые скобки необходимы, когда у вас 0, 2 или больше параметров () => expr or (p1, p2) => expr;
0 фигурные скобки в правой части представляют блок кода, в котором может содержаться несколько инструкций () => {};
0 при использовании такого синтаксиса неявного return нет, его нужно писать () => { return 'foo' }.
? Нельзя статически давать стрелочной функции имя, но тесты производительности намного лучше для большинства методов без имени.
? Стрелочные функции привязаны к лексическому окружению:
0 this это тот же контекст this, что и в родительском лексическом окружении;
0 this нельзя изменить при помощи .call, .apply, или похожих методов “reflection”-типа.
? Прочитайте ES6 Arrow Functions in Depth.

Шаблонные строки

? Строки можно объявлять при помощи обратных кавычек (`) в дополнение к одинарным и двойным.
? Строки с обратными кавычками являются шаблонными строками.
? Шаблонные строки могут быть многострочными.
? Шаблонные строки позволяют производить промежуточные вычисления `ponyfoo.com is ${rating}`, где rating – это переменная.
? Можно использовать любое валидное js-выражение для вычисления, например: `${2 * 3}` или `${foo()}`.
? Можно использовать помеченные шаблоны, чтобы изменить логику вычисления промежуточных значений:
0 добавить префикс fn к fn`foo, ${bar} and ${baz}`;
0 fn вызывается единожды с template, ...expressions;
0 template – это ['foo, ', ' and ', ''], а expressions – это [bar, baz];
0 результат fn становится значением шаблонной строки;
0 возможные примеры использования: очистка вводимых выражений от лишних данных, парсинг параметров и т. д.
? Шаблонные строки практически во всем лучше строк, обернутых в одинарные или двойные кавычки.
? Прочитайте ES6 Template Literals in Depth.

Литералы объектов

? Вместо { foo: foo }, можно писать просто { foo } – сокращенная форма записи пары свойство–значение.
? Вычисляемые имена свойств: { [prefix + 'Foo']: 'bar' }, где prefix: 'moz' возвращает { mozFoo: 'bar' }.
? Нельзя одновременно пытаться использовать две предыдущих особенности, запись {[foo]} – невалидна.
? Определения методов можно сделать более лаконичными при помощи следующего синтаксиса: { foo () {} }.
? Смотрите также секцию Object.
? Прочитайте ES6 Object Literal Features in Depth.

Классы

? Не «традиционные» классы, а синтаксический сахар поверх механизма наследования прототипов.
? Синтаксис похож на объявление объектов class Foo {}.
? Методы экземпляра new Foo().bar объявляются при помощи упрощенного синтаксиса литералов объекта class Foo { bar () {} }.
? Статические методы – Foo.isPonyFoo() – нуждаются в префиксе, ключевом слове static class Foo { staticisPonyFoo () {} }.
? Метод конструктора class Foo { constructor () { /* initialize instance */ }.
? Прототипное наследование с упрощенным синтаксисом class PonyFoo extends Foo {}.
? Прочитайте ES6 Classes in Depth.

Let и Const

? let и const – это альтернативы var при объявлении переменных.
? let имеет блочную область видимости, а не лексическую, по отношению к родительской функции.
? let поднимается в верхнюю часть блока, в то время как var поднимается в верхнюю часть функции.
? «Временная мертвая зона» или просто ВМЗ:
0 начинается в начале блока, в котором происходит объявление let foo;
0 заканчивается в том месте кода, где происходит объявление let foo (здесь «подъем» не имеет значения);
0 попытки доступа или определения foo внутри ВМЗ (до того, как будет выполнена инструкция let foo) приведут к ошибке;
0 помогает сократить число загадочных багов, в которых значение переменной претерпевает изменения раньше, чем происходит ее объявление.
? const также имеет блочную область видимости, «подъем» и следует семантике ВМЗ.
? Переменные const должны быть объявлены при помощи инициализатора const foo = 'bar'.
? Определение const после инициализации побуждает тихую ошибку (или не тихую – в строгом режиме).
? Переменные const не делают переменную неизменяемой:
0 const foo = { bar: 'baz' } значит, что foo всегда будет ссылаться на объект в правой части выражения;
0 const foo = { bar: 'baz' }; foo.bar = 'boo' не бросит исключение.
? Определение переменной с таким же именем – бросит.
? Предназначен для того, чтобы исправлять ошибки, когда вы переопределяете переменную и теряете ссылку на первоначальный объект.
? В ES6 функции имеют блочную область видимости:
0 предотвращают утечку данных через механизм «всплытия» { let _foo = 'secret', bar = () => _foo; };
0 не ломают пользовательский код в большинстве ситуаций и, как правило, являются тем, что вам нужно.
? Прочитайте ES6 Let, Const and the “Temporal Dead Zone” (TDZ) in Depth.

Комментарии (55)


  1. dom1n1k
    06.11.2015 22:19

    Я все-таки пока слабо понимаю, зачем сейчас нужен ES6 на фронте (с нодой вопросов нет) — ведь все равно приходится все конвертировать в 5 версию. Ну окей, какая-то часть нового функционала является просто синтаксическим сахарком и потому засовывается в режим совместимости безболезненно (например, стрелочные функции или let). Но вот классы и их наследование бабель конвертит в какие-то настолько жуткие и уродливые конструкции, что я лучше по старинке напишу.

    Вот если бы можно было большинству клиентов подсовывать нативный es6 и только в старые браузеры отдавать бабель-версию, было бы понятно. А так все равно все будут жевать транс-компилированную версию.

    Или я что-то не понимаю?


    1. SerafimArts
      06.11.2015 22:42
      +1

      Ну это как сравнивать паскаль и дельфи. В одном есть ООП, в другом его можно изобразить. Вроде даже похожие языки, но код в результате совершенно другой, не столько по синтаксису (и это тоже), сколько по стилистике.

      Ну вот, для примера, небольшой набросок ActiveRecord на ES2015 (под клиент): https://gist.github.com/SerafimArts/cc85891cffb7c1fd235e


      1. dom1n1k
        06.11.2015 22:54

        Я понимаю, в чем достоинства ES6. Я не понимаю, как их сейчас по-нормальному использовать, если даже обладатели самых новых браузеров всё равно будут получать бабель-суррогат.


        1. SerafimArts
          06.11.2015 22:56
          +10

          А исходники зато чистые и красивые.

          А как использовать нынче Go, Rust, C#, C++, etc, если даже обладателя самых новых процессоров будут получать ассемблер-суррогат? ;)


          1. PerlPower
            07.11.2015 18:01
            +1

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

            И если уж вдаваться в детали, то программы на описанных вами языках пишутся для работы в одном, максимум 2-3 окружениях, это в конце концов не ANSI C. А сгенерированный ES5 будет работать минимум в 4 разных браузерах, которые еще и будут разных версий.

            Кстати уважаемое JS-сообщество может дать мне ответ, почему оно в массе своей так радостно ждало ES6, который по факту работает в продакшене и будет работать еще минимум год исключительно через трансляторы, но все это время игнорировало clojurescript, coffescript, typescript — инструменты для которых воркфлоу один и тот же что и для текущего ES6?


            1. rPman
              07.11.2015 18:26
              +1

              Может потому что вероятность протащить 'clojurescript, coffescript, typescript — инструменты' в браузеры нативно намного меньше, чем поддержка ES6?


              1. PerlPower
                07.11.2015 18:33

                Но через год будет es2016, который опять таки будет поддерживаться только через трансляцию, а потом еще через год…

                Понимаете, тут фундаментальная проблема в том, что в вебе ВСЕГДА будут старые броузеры. Поэтому единственный способ обеспечить работоспособность приложения у максимального числа пользователей — это транслировать в некую старую версию JS.

                Так почему все проснулись только когда вышел es6, хотя по сути его использование ничем не отличается от того же coffeescript? Та же трансляция, та же отладка через сорц-мапы.


                1. yatagarasu
                  08.11.2015 15:55

                  Тут всетрчаются две мысли — зачем «самом модному хипстерскому сервису» поддержка каких-то там старых браузеров и зачему самому наджному древнему энтерпрайзу, все эти модные фишечки esXXXX.
                  Так что проблема я считаю надуманна, эти два множества никак не пересекаются.


                1. Argutator
                  08.11.2015 16:34

                  Понимаете, тут фундаментальная проблема в том, что в вебе ВСЕГДА будут старые броузеры.

                  Таки лёд тронулся же. Тот же Microsoft отошел от именования версий браузеров — будет один Edge обновляемый подобно хрому. Использование старых версий в таком случае получается следованием принципу «сам себе злобный Буратино» — так можно и обновления безопасности, закрывающие дырки продуктов не ставить и потом страдать от того, что ими кто-то воспользовался.


        1. SerafimArts
          06.11.2015 23:06

          Я немного подумал и наконец понял в чём реально вопрос. Если я не угадал — просьба поправить.

          Так вот, весь код на ES2015 (и даже ES2016) запросто переводится на ES5, включая даже некоторые API, вроде Map, Set и т.д., которые вроде как входят в спецификацию. Единственная проблема — это Proxy — единственное что невозможно транслировать и пока очень слабо поддерживается даже самыми современными браузерами. В остальном — абсолютно весь код можно запускать на любом браузере, используя все возможности современных версий даже на каких-нибудь относительно старых версиях браузеров (в пределах разумного конечно, не ИЕ6 какой-нибудь, хотя кто знает...).

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


          1. bethrezen
            07.11.2015 10:16

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

            Боюсь, что через 5 лет появится уже какой-нибудь ES2020, который вообще ни в одном месте не совместим ни с одним браузером. И опять всем придётся пользоваться babel или его аналогами.
            Ну либо js браузерный всё же будет развиваться в другую сторону, нежели (io|node).js.


            1. SerafimArts
              07.11.2015 19:40

              Когда то было предложение (ссылку на статью на хабре я сейчас не найду) добавляющая в браузеры возможность передачи байткода, так что компилировать к 2020му году всё равно будет выгоднее, даже при условии, что браузеры будут поддерживать синтаксис этого ES2020. Ну это при условии, что браузеры начнут поддерживать этот байткод.



        1. SerafimArts
          06.11.2015 23:11

          P.S. А для создания читаемых классов можно использовать опцию loose es6.classes (в документации есть). Это сделает исходный код на выхлопе в разы читаемей (правда в результате не на 100% совместимый со стандартом). Хотя при наличии source maps читаемость результата и так не должна доставлять проблем.


        1. TycoooN
          07.11.2015 00:52
          +6

          Какая разница, что там получает браузер, если оно работает, как задумано? Вся соль в удобстве разработки.


          1. dom1n1k
            07.11.2015 01:31
            -4

            Я сейчас в песочнице просто из головы набрал

            простенький пример, 24 строчки
            class Apple {
              constructor(color, weight) {
                this.color = color;
                this.weight = weight;
              }
              get cost () {
                let price = 100;  // rub/kg
                let coeff = {
                  green:   1,
                  yellow:  1.2,
                  red:     1.5,
                  magenta: 1.8
                };
                return this.weight * price * (coeff[this.color] || 1);
              }
            };
            
            class RedApple extends Apple {
              constructor(weight) {
                super();
                this.color = "red";
                this.weight = weight;
              }
            };
            


            1. dark_ruby
              07.11.2015 02:07
              +3

              вы когда на C#/Java/etc пишите, тоже потом скомпилированный байткод изучаете?
              смысл использвания ES6 в том что вы получаете новые фишки языка, которые можете использовать сегодня! в том что вашь код становитсья коротким и понятным с первого взгляда, и.т.д.


            1. zxcabs
              07.11.2015 04:47
              +2

              Нормально все будет и 1000 строк и с 10 000 тысячами, код пишется в первую очередь для людей, поэтому то как он выглядит для машины не имеет ровным счетом никакого значения.
              Во вторых, аргумент за производительность вообще не аргумент в этом контексте, я вам дам 100% гарантию что ваше приложение сначала начнет тормозить сначала из-за неправильной работы с дом, потом из за криворукости реализации, потом из за монстрячей конструкции какого нибудь фреймворка, примерно к концу списка тормоза можно будет объяснить вспышками на солнце, но и даже в этом случае тормоза из за кода трансплиттера будут еще далеко.


            1. SerafimArts
              07.11.2015 06:30

              Я уже написал выше — используйте loose mode, выхлоп сокращается до 50 с копейками строк, но не гарантируется 100% совместимость со стандартом (правда на практике никаких проблем с этим нет, если не влезать во внутренности реализации).


            1. ankh1989
              07.11.2015 07:34

              Если вы там нейросети на JS пишете (это про вашу неуверенность в быстроте), то лучше наверно использовать emscripten.


            1. oWeRQ
              10.11.2015 12:29
              +1

              Добавляется 70 строк общих фукций(если отформатировать), считай runtime, сами классы остаются довольно читабильными и не сильно жиреют. +6 строк в данном примере. Если убрать геттер и включить loose mode — код почти как рукописный, с прототипами и анонимными фукциями.


    1. noder
      07.11.2015 00:17
      +2

      А зачем пользователям отдавать исходные коды? Сейчас уже практически везде используют средства сборки/минификации скриптов и стилей. Использовать es6 для разработки на JavaScript повышает производительность и удобство разработки.


      1. rPman
        07.11.2015 18:30
        -3

        Попробуйте исследовать лицензии ваших любимых компонент, которые вы используете на javascript (или кстати любом другом скриптовом языке), и вы поймете, что либо вам придется отказываться от них, либо перелицензировать, либо принудительно открывать свои исходники, так как оно почти все GPL (правда часто LGPL или аналог).

        p.s. кстати, а использование таких компиляторов из чегототам в javascript разве не освобождает программистов от необходимости выкладывать ИСХОДНЫЙ текст программы, если это требует лицензия на компоненты?


        1. symbix
          07.11.2015 18:58
          +2

          Гм. Использую десятки сторонних библиотек, везде MIT/BSD-лицензия.


  1. PerlPower
    07.11.2015 05:01
    +1

    Спасибо вам за перевод. Постарайтесь пожалуйста внимательнее относиться к опечаткам. И по возможности выделять код так же как и в оригинале. Но поскольку на хабре туго с форматированием, придется ограничиться <font color="#112233">.

    ? var {foo} = pony то же, что var foo = pony.foo.


    1. Darina_PL
      07.11.2015 12:09

      Спасибо, поправила опечатку. Когда буду заливать вторую часть, поправлю весь код по цвету.


    1. klierik
      07.11.2015 15:28
      +4

      Если честно, то перевод у вас, мягко сказать, не очень хороший. Вчера ребята из css-live запостили перевод этой статьи, вы извините, но по сравнению с вашим — земля и небо. Сравните сами.


    1. menelion_elensule
      08.11.2015 22:43

      Извините, по этому же поводу вопрос: а маркированные списки в оригинале тоже на самом деле не были HTML-списками? А то читать не очень удобно(


  1. funca
    07.11.2015 18:12

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

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

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

    Теперь, наряду некоторым набором определенно полезных вещей, в спецификацию вбросили адову кучу синтаксических трюков, что усложняет язык в разы. Снаружи добавилось интсрументирование — трансплитеры уже необходимость. Если они собираются менять и спецификацию каждый год, то скоро эпохе JS придет конец.


    1. rPman
      07.11.2015 18:45

      Я вообще удивлен, что в браузерах до сих пор не установлена (и главное грамотно открыт доступ к компонентам) песочница с LLVM машиной, тогда разработчики могли бы работать с любым языком… да и с библиотеками, так хочется чтобы они в браузере ставились (загружались) не каждый раз при заходе, а устанавливались из репозитариев, желательно с cdn или с использованием p2p…


      1. funca
        07.11.2015 19:39

        Наверняка, о чем-то подобном мечтали и разработчики Sliverlite. Думаю здесь работает эффект «вавилонской башни» (я имею ввиду ту часть этой истории, когда люди говорили на одном языке, а потом их наказали). WEB основан на сравнительно небольшом множестве простых концепций, поддержанных в открытых стандартах. Мне кажется, что в таких масштабах профит от использования единого для всех языка перевешивает все недостатки (даже на сервер js притащили). Мультиязычность неплохо работает в огороженных мирках, но в массе, дробит сообщество и увеличивает хаос.


        1. rPman
          07.11.2015 19:54

          Именно Microsoft Silverlight был не способом исправить текущую ситуацию с языками, а способ затмить собой Adobe Flash со всеми вытекающими от сюда минусами от монополии.

          LLVM полностью открыто, поддерживается сразу несколькими компаниями, УЖЕ имеет поддержку большого количества оборудования и вообще, я не понимаю, почему все на него не переходят дружными рядами.


    1. Large
      08.11.2015 13:21

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


      1. Zenitchik
        09.11.2015 13:04

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


        1. Large
          09.11.2015 13:37

          Да, это удобно, хотя тоже всего лишь сахар для обращения к родителю. Сейчас тоже ничто не мешает создать на него ссылку и записать ее в super.


          1. Zenitchik
            09.11.2015 15:36

            Конечно, можно. Каждый, кому не лень, писал свой велосипед.
            Дело в том, что предложенный стандарт выглядит недоделанным. Скажем, переменная this существует всегда, можно заглянуть в спецификацию и узнать, чему она равна в каждом конкретном случае.
            А вот super…


            1. Large
              09.11.2015 16:46

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


              1. Zenitchik
                09.11.2015 16:50

                Проблема в том, что под капотом — prototype. С классами работать не всегда удобно. Класса у меня вообще может не быть, а super, тем не менее, нужен. Приходится в одном месте использовать нативный, а в другом — самоделку.


  1. saggid
    07.11.2015 23:16
    +3

    Большое спасибо за перевод полезного материала)

    По теме ES2015 — немного понять для себя лично не могу до сих пор… Есть ли там действительно великие по полезности нововведения? Ну, появились let, const, ну, получили мы новые типы хешей. Синтаксический сахар — это вообще мелочь, хотя и приятно иногда с ним, но крайней необходимости в нём никогда не ощущал. Ну, «классы» теперь есть. Хотя я и раньше просто функцию создавал и запихивал в неё все нужные методы, мало чем от класса в итоге оно отличается.

    Так есть ли там что-нибудь из реальных killer features? Может ли кто-нибудь пояснить?)


    1. jMas
      08.11.2015 02:39

      ИМХО, сделали вещи которые помогут чуть меньше наступать на грабли. Например, хотя бы объявление классов. Для людей из других ЯП код JS с новыми классами будет выглядеть привычней, да и мусора будет немного меньше. Некоторые штуки, пока с ними все не столкнутся — будут вызывать только недоумение, хотя на практике будут делать код короче (я сейчас о fn(...arr), это ведь действительно быстрее, чем fn.apply(this, arr)). Пока я увидел кучу синтаксического сахара, и трудно себе представляю код, который будет им изобиловать (сейчас я не о классах). Для меня он в читабельности несколько потеряет, пока я не освою все мельчайшие нюансы.
      Интересно, а есть у разработчиков планы по решению бородатых неточностей JS?


      1. SirEdvin
        08.11.2015 12:00

        Ну, это выглядит как стандартизация костылей.
        К тому же это странно, с одной стороны делать вход в язык для разработчиков проще, а с другой стороны добавлять такой адский синтаксический сахар как в разделах Assignment Destructuring и прочих.
        Особенно { foo } выглядит совсем странно.


      1. Zenitchik
        09.11.2015 13:06
        +2

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

        Боюсь именно поэтому мусора станет больше, т.к. люди из других ЯП будут ещё реже заглядывать в спецификацию JS.


    1. SerafimArts
      08.11.2015 12:38
      +2

      Киллер фичи в основном в ES2016 есть, но так как мы все дружно пользуемся бабелом — разницы никакой. Сами фичи: async\await, проперти и декораторы

      В ES2015 можно полукиллерфичами назвать как минимум import\export, классовые геттеры\сеттеры и генераторы + символ итератор метод.


      1. Large
        08.11.2015 13:33

        Так import/export пока нет так как Loader API не определили. Его скорей всего в 2016 добавят.


    1. Large
      08.11.2015 13:28

      Map, Set, Proxy, Reflect, Symbols, Promises, subclasses, generators, iterators, tail call optimisation — по моему достаточно киллер фич. Конечно в 2016 добавят намного больше, в том числе асинхронные функции которые помогут писать код в синхронном силе с помощью промисов. Но и 2015 — это большой шаг в нужную сторону (хотя я лично немного сомневаюсь на счет классов).


  1. Large
    08.11.2015 13:17

    Обидно, что

    let [a, ...rest, b, c, d] = [1, 2, 3, 4, 5, 6, 7, 8];
    

    не работает и нужно его расписывать в 2 хода:
    let [a, ...rest] = [1, 2, 3, 4, 5, 6, 7, 8];
    let [b, c, d] = rest.splice(-3);
    


    На самом деле не совсем понятно в чем разница при использовании между отсутствием всплытия и наличием ВМЗ. В реализации разница есть, но поведение как мне кажется от этого не меняется.

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

    В описаниях классов вообще противоречия:
    Методы экземпляра new Foo().bar объявляются при помощи упрощенного синтаксиса литералов объекта class Foo { bar () {} }.

    при этом такую конструкцию приводят в пример как замену Foo.prototype.bar. Насколько мне известно — верно второе, да и babel записывает данные методы в прототип, а не в экземпляр.


    1. Arilas
      09.11.2015 02:37
      -2

      На самом деле работает первый пример, даже несколько… в одном массиве, вот пример:

      export function arrayRemove(state:Array, index:Number):Array {
          return [
              ...state.slice(0, index),
              ...state.slice(index + 1, state.length)
          ]
      }
      export function arrayReplace(state:Array, index:Number, newItem:Object):Array {
          return [
              ...state.slice(0, index),
              newItem,
              ...state.slice(index + 1, state.length)
          ]
      }
      

      Даже так можно


      1. Large
        09.11.2015 02:51

        На самом деле нет (можете проверить в ff). В вашем примере нет ни диструктивного присваивания ни переменных аргументов функции потому он и работает.


  1. Nesvet
    08.11.2015 13:22
    +2

    let поднимается в верхнюю часть блока, в то время как var поднимается в верхнюю часть функции.

    let не поднимается. Пруф:
    In ECMAScript 6, let does not hoist the variable to the top of the block.


    1. SelenIT2
      09.11.2015 12:03

      На той же mozilla.org есть и пруф, что поднимается:

      There’s still hoisting with let, but it’s not as indiscriminate.

      И автор переведенной статьи отдельно подчеркивает это в ответе на первый же коммент (в котором, что интересно, тоже говорится о том, что «let (and const) hoist (with TDZ) to the top of the closest containing scope contour (block, function, or global)»!):
      Allen, I meant let is hoisted just like var is hoisted, not that they’re hoisted in the same way.

      Надеюсь, кто-нибудь из грамотных людей поможет рассудить…


      1. rock
        09.11.2015 12:23

        Ну можно сказать и поднимается, создавая TDZ, это скорее вопрос терминологии :)

        if(true){
          typeof x === 'undefined'; // ReferenceError
          let x = 42;
        }
        


  1. rayz_razko
    09.11.2015 16:26
    +3

    var {foo: {bar: deep}} = { foo: { bar: 'baz' } } даст вам deep: 'baz'.
    наверное меня сейчас заминусуют, но это же ад какой-то. Если такого будет много, как такое можно читать, особенно бегло?


    1. zxcabs
      09.11.2015 16:33

      То что есть такая возможность не значит что в таком виде этим будут пользоваться везде и всюду.
      По опыту могу сказать что такая запись

      let
          { foo, bar, baz } = this.prop;
      


      Читается вполне себе удобно и становится вполне привычной.


    1. develop7
      10.11.2015 13:12
      -1

      это же недоpattern matching, что здесь сложного?


  1. raacer
    10.11.2015 16:30

    Обзор ES6 в 350 пунктах. Часть первая

    o_O