Новые фичи восьмой редакции EcmaScript.

image

EcmaScript 8 или EcmaScript 2017 был официально выпущен комитетом TC39 в конце июня. Кажется, мы много говорили о EcmaScript в прошлом году и это было не просто так. На данный момент стандартом является выпуск новой спецификации раз в год. ES6 был опубликован в 2015, а ES7 в 2016, но кто-нибудь помнит, когда вышел ES5? Это было в 2009 году, до волшебного взлета JavaScript.

Итак, мы следим за изменениями в разработке стабильного языка JavaScript, и теперь нам надо добавить ES8 в свой лексикон.


Суровые люди, могут сделать глубокий вдох и прочитать web или PDF версию спецификации. Для остальных в этой статье мы рассмотрим главные новые возможности ES8 с примерами.

Паддинги строк


В этом разделе добавлены две функции в объект String: padStart и padEnd. Как можно понять из их названия, цель этих функций – дополнить строку от начала или конца так, что в результате строка достигнет указанной длины. Вы можете дополнить строку определёнными символами или пробелами по умолчанию.

Вот декларация функций:

str.padStart(targetLength [, padString])
str.padEnd(targetLength [, padString])

Как видно, первый параметр этих функций targetLength – это полная длина итоговой строки. Второй опциональный параметр padString – это строка для дополнения исходной строки. По умолчанию – пробел.

'es8'.padStart(2);          // 'es8'
'es8'.padStart(5);          // '  es8'
'es8'.padStart(6, 'woof');  // 'wooes8'
'es8'.padStart(14, 'wow');  // 'wowwowwowwoes8'
'es8'.padStart(7, '0');     // '0000es8'
'es8'.padEnd(2);          // 'es8'
'es8'.padEnd(5);          // 'es8  '
'es8'.padEnd(6, 'woof');  // 'es8woo'
'es8'.padEnd(14, 'wow');  // 'es8wowwowwowwo'
'es8'.padEnd(7, '6');     // 'es86666'

image

Object.values и Object.entries


Метод Object.values возвращает массив собственных перечисляемых свойств переданного объекта в том же порядке, который предоставляет цикл for in.
Декларация функции тривиальна:

Object.values(obj)

Параметр obj – исходный объект для операции. Это может быть объект или массив (который является объектом с такими индексами [10, 20, 30] -> { 0: 10, 1: 20, 2: 30 } ).

const obj = { x: 'xxx', y: 1 };
Object.values(obj); // ['xxx', 1]

const obj = ['e', 's', '8']; // same as { 0: 'e', 1: 's', 2: '8' };
Object.values(obj); // ['e', 's', '8']

// когда мы используем числовые ключи, значения возвращаются 
// в порядке сортировки по ключам
const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz' };
Object.values(obj); // ['yyy', 'zzz', 'xxx']
Object.values('es8'); // ['e', 's', '8']

image

Метод Object.entries возвращает массив собственных перечисляемых свойств переданного объекта парами [ключ, значение] в том же порядке, как и Object.values.

Декларация тривиальна:

const obj = { x: 'xxx', y: 1 };
Object.entries(obj); // [['x', 'xxx'], ['y', 1]]

const obj = ['e', 's', '8'];
Object.entries(obj); // [['0', 'e'], ['1', 's'], ['2', '8']]

const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz' };
Object.entries(obj); // [['1', 'yyy'], ['3', 'zzz'], ['10': 'xxx']]
Object.entries('es8'); // [['0', 'e'], ['1', 's'], ['2', '8']]

image

Object.getOwnPropertyDescriptors


Метод getOwnPropertyDescriptors возвращает дескрипторы собственных свойств указанного объекта. Дескриптор собственного свойства это тот, который определён прямо у объекта, а не унаследован от его прототипа.
Декларация функции такая:

Object.getOwnPropertyDescriptor(obj, prop)


obj – исходный объект и prop – имя свойства, дескриптор которого нужно получить. Возможные ключи в результате: configurable, enumerable, writable, get, set и value.

const obj = { get es8() { return 888; } };
Object.getOwnPropertyDescriptor(obj, 'es8');
// {
//   configurable: true,
//   enumerable: true,
//   get: function es8(){}, // функция геттер
//   set: undefined
// }

Данные дескрипторов очень важны для таких продвинутых фич, как декораторы.

image

Лишние запятые в списке параметров функции и вызове


Возможность указать лишние запятые в параметрах функции позволяет не получать ошибку (SyntaxError) когда мы добавили запятую в конце списка:

function es8(var1, var2, var3,) {
  // ...
}

Как и в объявлении функции, этот синтаксис можно использовать и при её вызове:

es8(10, 20, 30,);

Эта возможность была вдохновлена лишними запятыми в литералах объекта { x: 1, } и литералах массива [10, 20, 30,].

Асинхронные функции


Объявление async function определяет асинхронную функцию, которая возвращает объект AsyncFunction. Внутреннее устройство асинхронных функций работает подобно генераторам, но они не транслируются в функции генератора.

function fetchTextByPromise() {
  return new Promise(resolve => { 
    setTimeout(() => { 
      resolve("es8");
    }, 2000);
  });
}
async function sayHello() { 
  const externalFetchedText = await fetchTextByPromise();
  console.log(`Hello, ${externalFetchedText}`); // Hello, es8
}
sayHello();

Вызов sayHello выведет Hello, es8 через 2 секунды.

console.log(1);
sayHello();
console.log(2);

Напечатает:

1 // сразу
2 // сразу
Hello, es8 // через 2 секунды

Это связано с тем, что вызов функции не блокирует поток выполнения.

Обратите внимание, что async function всегда возвращает промис и ключевое слово await может использоваться только в функциях с ключевым словом async.

image

Разделяемая память и атомарные операции


Когда память разделяемая, множество потоков может читать и писать те же данные в памяти. Атомарные операции позволяют убедиться, что предсказуемые значения записаны и прочитаны, что операции завершены до начала следующих операций. В этом разделе представлен новый конструктор SharedArrayBuffer и объект Atomics со статическими методами.

Объект Atomics – это набор статических методов как Math, так что мы не сможем вызвать его конструктор. Примеры статических методов этого объекта:

  • add / sub — добавление / вычитание значения из значения в указанной позиции
  • and / or / xor? —? побитовое «И» / побитовое «ИЛИ» / исключающее «ИЛИ»
  • load ?—? получение значения в указанной позиции

image

И один момент на следующий год в ES9 – снятие ограничений для шаблонных литералов


С тегированными шаблонными строками (ES6) мы можем делать такие штуки, как объявление функций для парсинга шаблонов и возвращения значений согласно какой-то логике.

const esth = 8;
helper`ES ${esth} is `;
function helper(strs, ...keys) {
  const str1 = strs[0]; // ES
  const str2 = strs[1]; // is
  let additionalPart = '';
  if (keys[0] == 8) { // 8
    additionalPart = 'awesome';
  }
  else {
    additionalPart = 'good';
  }
  
  return `${str1} ${keys[0]} ${str2} ${additionalPart}.`;
}

Вернется значение > ES 8 is awesome. И для esth равным 7 вернётся > ES 7 is good.

Но существуют ограничения для шаблонов, которые содержат подстроки \u или \x. ES9 решит проблему экранирования. Читайте подробнее на сайте MDN или в документе TC39.

image

Заключение


JavaScript уже в продакшене, но всегда обновляется. Процесс принятия новых возможностей в спецификацию очень организован и устойчив. На последнем этапе этот функционал подтверждается комитетом TC39 и реализуется основными разработчиками. Большинство из них уже реализовано в языке Typescript, браузерах или разных полифиллах, так что вы можете пробовать их уже сейчас.
Поделиться с друзьями
-->

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


  1. domix32
    12.07.2017 10:46
    +2

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


    1. mannaro
      12.07.2017 11:20
      +2

      Да, и таких фич много.


    1. theTeacherOfEnglish
      12.07.2017 12:20

      В последнее время в стандарт просто входят часто используемые фичи из
      1. браузеров
      2. из сторонних библиотек, типа JQuery или Lodash
      И это в целом круто )


  1. fljot
    12.07.2017 12:20

    По-прежнему нет слабых ссылок :/


    1. faiwer
      12.07.2017 14:12
      +1

      Вы имеете ввиду что-то вроде weakMap & weakSet, только в виде одиночной ссылки, которая может "протухнуть", не блокируя GC?


      1. fljot
        12.07.2017 21:46

        Да (и такое бы можно было организовать, если бы WeakMap/WeakSet можно было бы проитерировать).


  1. DreamChild
    12.07.2017 12:20
    +1

    В первой таблице поддержки (для функций паддинга) указана версия IE 15. Разве такая вообще существует?
    Вероятно имеется в виду Edge, но он в той же таблице указан рядом как отдельный браузер.


    1. vlanko
      12.07.2017 21:10
      +2

      этот баг, вероятно, остался с тех времен, когда ИЕ что-то поддерживал.


  1. Leg3nd
    12.07.2017 12:20
    +4

    Лишние запятые в списке параметров функции и вызове

    WTF…


    1. Avenger911
      12.07.2017 12:39
      +6

      очевидно, чтобы при записи в столбик окончания строк не отличались:


      let someArray = [
        longElement1,
        longElement2,
        longElement3,
      ];
      
      someFunction(
        longParam1,
        longParam2,
        longParam3,
      )


      1. rayz_razko
        12.07.2017 12:49

        И это теперь чатсь спецификации? WTF?


        1. Avenger911
          12.07.2017 13:09
          +9

          Ну а почему бы и нет, если в литералах массивов и объектов это уже есть? И частью чего ещё это должно быть?


          1. Alexeyco
            12.07.2017 14:50
            -5

            Есть, но ESLint базово требует убирать висячие запятые в объектах.


            1. justboris
              12.07.2017 15:31
              +10

              Eslint настраиваемая штука, по умолчанию он ничего не требует.


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


              1. comerc
                13.07.2017 00:04

                А если прикрутить Prettier, то оно вообще не парит.


                1. justboris
                  13.07.2017 11:18

                  Да, но там эта опция тоже за флагом --trailing-comma=all. По дефолту конечные запятые не ставятся/убираются


                  1. comerc
                    13.07.2017 22:01

                    Я сейчас на PHP (по требованию заказчика) сочиняю API. После 5-ти летней паузы. Вот откуда ноги растут с этими запятыми!


      1. Leg3nd
        13.07.2017 11:39
        +1

        Да я, в принципе, сразу так и понял, так как это единственная разумная причина такое добавлять. Но что-то внутри меня перевернулось)
        Куда менее прятный вот такой момент я нашел в документации мозиллы по поводу AsyncFunction:

        Выполнится за 4 секунды, как и ожидаемо.

        async function add2(x) {
          var a = await resolveAfter2Seconds(20);
          var b = await resolveAfter2Seconds(30);
          return x + a + b;
        }
        


        А вот этот кусок кода выполнится за 2 секунды. Как по мне, вообще не очевидно, не смотря на то, что может оказаться вполне удобным для использования.
        async function add1(x) {
          var a = resolveAfter2Seconds(20);
          var b = resolveAfter2Seconds(30);
          return x + await a + await b;
        }
        


        1. justboris
          13.07.2017 11:49
          +1

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


          А если все равно неочевидно получается, то всегда можно переписать фрагмент кода на ручные вызовы .then().


          1. Leg3nd
            13.07.2017 12:14
            +1

            Для меня не очевидно потому что await означает, что мы ждем окончания асинхронной операции при его наличии. И логично что, если два await явно указано, то и ожидание должно происходить два раза. А чтобы дождаться нескольких результатов асинхронных функций как бы существует Pormise.all(). Он как раз явно и указывает на этот процесс.
            Понятно, что во втором примере с использованием Promise.all() больше кода получится. Но с другой стороны, во втором примере на параллельность получения результатов указывает только то, что await'ы находятся в выражении, которое возвращается из aync функции и больше ничего. Такое легко забыть, пропусть… короче не очевидно как по мне.


            1. faiwer
              13.07.2017 12:21
              +1

              Поверьте, после пары дней активного использования async-await это всё будет не только очевидно, но и доведено до автоматизма. Особенно если до этого был опыт работы с Promise-ми. Те же генераторы куда сложнее для понимания, имхо.


              1. Leg3nd
                13.07.2017 12:53
                +1

                Вот по поводу генераторов — как то не нашел для себя полезного применения им в повседневных задачах…


                1. faiwer
                  13.07.2017 13:53

                  Ими удобно реализовывать то, для чего они предназначены — протоколы итерации каких-либо коллекций. А это бывает востребованным при написании библиотек. Какие-нибудь там парсеры, конвертеры и пр. Где есть свои типы коллекций и итераторов по ним. В общем штука достаточно специфичная.


                  1. raveclassic
                    13.07.2017 13:58

                    Мне кажется, что основной фишкой является отменяемость. Потом идет тестируемость.


            1. mayorovp
              13.07.2017 12:22
              -1

              Вот именно, await означает что мы ждем окончания асинхронной операции — и ничего не говорит о начале этой операции.


              Параллельность ожидания случилась не потому что await находятся в выражении, а потому что между вызовами resolveAfter2Seconds нет вызова await.


              1. Leg3nd
                13.07.2017 12:28

                Согласен, забыл про этот момент.


          1. Leg3nd
            13.07.2017 12:20

            Вот если бы синтаксис был примерно такой:

            async function add1(x) {
              var a = resolveAfter2Seconds(20);
              var b = resolveAfter2Seconds(30);
              return await(x + a + b);
            }
            

            Вот тогда бы я согласился с Вами, что можно догадаться :)


            1. faiwer
              13.07.2017 12:24

              Предложенный вами синтаксис нереален, т.к. нотация methodName() запускает methodName сразу, а не по истечению какого-либо времени. К тому же await-ить можно всё что угодно, что умеет метод .then, а не только async method-ы.


            1. justboris
              13.07.2017 12:31

              Скорее вот так


              async function someAction(x) {
                const a = someAsyncOperation();
              
                // куча разного другого кода
              
                await a;
              }

              по вашей логике someAsyncOperation должна не выполняться сразу, а ждет, пока ее не за-await-ят. А что будет, если await не сделают никогда? Операция не выполнится вообще?


              1. Leg3nd
                13.07.2017 12:40
                +2

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


                1. faiwer
                  13.07.2017 13:55

                  что вызов асинхронной фунции

                  помимо прочего это может быть и не асинхронная функция, а самая обыкновенная. И эта функция даже не обязательно должна возвращать promise, хотя это уже несколько странно :)


        1. Avenger911
          13.07.2017 12:21

          Ага, значит несколько await в одном выражении ожидаются параллельно. Важный момент, как мне кажется, потому что независимые вызовы нет смысла выполнять поочерёдно. Спасибо за информацию!


          1. mayorovp
            13.07.2017 12:23

            Нет. Операторы await всегда ждут последовательно!


            А вот сами асинхронные операции могут без особых проблем идти параллельно. Надо просто не путать вызов асинхронной функции и ожидание его результата.


            1. Avenger911
              13.07.2017 12:31

              Хм, точно! Кажется я понял идеологию, спасибо!


    1. DexterHD
      12.07.2017 17:39
      -6

      Поддерживаю. WTF? Культура кода, нет не слушал. Мы сделаем стандарт который будет разрешать что угодно. Хотите лишнюю запятую? Пожалуйста. Лишнюю закрывающую скобку? Не проблема? Чехарду с кавычками и без них, не вопрос. :) Пусть ребята которые занимаются реализацией нашего стандарта сами мозг ломают как всю эту магию реализовать. :)


      1. bro-dev
        12.07.2017 18:02
        +5

        Строгость нужно только тогда, когда отсутствие её может вызвать непредсказуемость.


      1. VolCh
        12.07.2017 21:57
        +4

        В некоторых стайлгайдах «лишняя» запятая является обязательной, если список разделяется на несколько строк. Это, в частности, позволяет обходиться одной строчкой diff на один добавленный в конец списка или удаленный с него. Вот это культура кода.


    1. Laney1
      12.07.2017 19:53
      +5

      не понимаю массового горения по поводу этой фичи. Например, она давно есть в питоне (откуда видимо и взята), никому там не мешает и широко используется


      1. ZetaTetra
        12.07.2017 22:44
        -1

        В .NET C# тоже такая фича с первой версии доступна.


        1. Vadem
          13.07.2017 10:22
          +2

          В C# такая фича доступна только для массивов и для инициализации объектов, а в питоне и для параметров функций тоже.


  1. animhotep
    12.07.2017 12:20
    +1

    ещё один способ асинхронного получения данных… когда уже найдётся «идеал»


    1. mayorovp
      12.07.2017 13:51
      +1

      Что значит — "еще один"? Это ж просто новый сахар для старого способа (обещаний-промизов).


  1. reilag
    12.07.2017 12:57
    +8

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

    image


  1. XeL077
    12.07.2017 13:19
    +5

    str.padStart(targetLength [, padString]);
    Наконец спасет многие библиотеки от странных зависимостей, аля npm left-pad или pad-left.


    1. impwx
      12.07.2017 13:54
      +1

      Если только на бэкенде — клиентский код все равно придется еще несколько лет обмазывать полифиллами.


      1. XeL077
        12.07.2017 13:57
        +1

        Frontend требует особые жертв и обрядов.


        1. Alexeyco
          12.07.2017 14:39
          +33

          Фронтэнд должен быть в удовольствие. Например «какое удовольствие, что я не фронтэндщик».


  1. MaxKorz
    12.07.2017 13:36

    Приятно, что большинство этих функций уже реализовано и используется в продакшене тем или иным путем:
    padStart, padEnd, Object.values и Object.entries уже давно являются частью core-js
    Асинхронные функции реализуются с помощью babel/typescript.

    То есть последние фичи можно использовать уже сейчас, а не ждать пару лет, пока большинство юзеров обновятся.


    1. RifleR
      12.07.2017 14:04
      +1

      Ну правильно, это обычный путь в стандарт — сначала используют стороннюю библиотеку для какой-то фичи, потом кто-то предлагает фичу в черновик стандарта, потом используют babel, а уже после добавления в стандарт отключают транпиляцию данной фичи — нативное использование… PROFIT!


  1. inoyakaigor
    12.07.2017 14:22

    А объясните кто-нибудь как работает эта фича:

    helper`ES ${esth} is `;
    

    Почему «склеивая» руками имя функции и шаблонную строку мы, получается, вызываем эту функцию с этой строкой в качестве параметра?




  1. samizdam
    12.07.2017 17:18

    Интересно, что все описываемые в публикации новшества, реализованы только в Firefox.
    Почему-то думал что Chrome развивается не менее динамично в этом направлении, ан нет.


    1. RifleR
      12.07.2017 18:25

      Вы не совсем правы, на самом деле сейчас все фичи ES2017 реализованы в Chrome, Firefox, Safari. Где-то в стабильной версии, где-то в бета-версии, где-то что-то пока под флагом. Но реализованы. Сейчас производители развивают браузеры в общем-то очень динамично. Чуть отстает только Edge, но и то не сильно.


    1. samsdemon
      12.07.2017 23:11
      +1

      Я раньше тоже на это смотрел, но потом узнал, что в сафари/вебките всё реализовано на 100% (или 99%), но какая разница, если в последнее время модно даже среди менеджеров просить делать progressive enhancement через Chrome, мол, если там оно работает, то добавьте плз чего-нибудь, всё равно половина пользователей через хром сидят. При этом если раньше это было только по CSS заметно (типа http://www.hongkiat.com/blog/css-image-set/, или ещё чего), то теперь появляются всякие Web Bluetooth и прочие, что не может не радовать


  1. rumkin
    12.07.2017 17:39
    +1

    Не "лишние", а "висячие" запятые и нужны они не для записи вида


    add(1,2,3,)

    а для записей вида:


    add(
        1,
        2,
        3,
    )

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


    1. AngReload
      12.07.2017 21:11

      Ещё можно не писать undefined при необязательных параметрах вызова:


      const fn = (a = 1, b = 2, c = 3) => [a, b, c];
      
      //Two similar function calls:
      
      fn(undefined, undefined, 42); // [1, 2, 42]
      
      //vs
      
      fn(, , 42); // [1, 2, 42]

      PS: Проверил: нет, так нельзя :-(


    1. vtvz_ru
      12.07.2017 21:15
      +5

      Это особенно актуально в Git. Если много аргументов и ты добавляешь еще один, то на выходе получается одна измененная строка. В старом случае, их было две: одна, где ты поставил запятую, и новая. Некий эстетический дискомфорт от подобного я испытываю, редактируя JSON файлы, где в конце ну никак нельзя оставить запятую, а запихать данные в середину не получается.


  1. dmitry_dvm
    12.07.2017 19:15
    -5

    padStart попахивает выравниванием пробелами в ворде. Это реально нужно?


    1. TheShock
      12.07.2017 21:30
      +3

      Ну, например, форматировать время удобно. «01:05»


      1. tugrik
        12.07.2017 22:19
        -1

        так даже немного короче:

        ('0'+1).slice(-2)
        '1'.padStart(2, '0')
        


        1. TheShock
          12.07.2017 22:40
          +1

          Так семантика хуже.


      1. dmitry_dvm
        13.07.2017 21:15

        А разве совать верстку в логику не дурной тон?


        1. Chamie
          13.07.2017 21:22
          +1

          Вы React видели?


        1. justboris
          13.07.2017 23:04
          +1

          А где здесь логика?


          Например сложение firstName + ' ' + lastName — это же верстка?


          Тогда отчего value.padStart(2, '0') внезапно оказывается логикой?


          1. dmitry_dvm
            14.07.2017 16:45
            -1

            В моем MVVM-мире firstName + ' ' + lastName — это как раз таки логика в верстке, ибо такие вещи делаются через байндинг полей модели к элементам верстки. Но это у меня в MVVM. В фронтенде, видимо, многое иначе.
            Кстати насчет камента выше про реакт. Уверен, следующий реакт будет именно с отделением кода от верстки, всё идет по кругу. Раньше тоже лепили всё в один хтмл, потом разделили, а сейчас опять слепили. Значит скоро опять разделят.


            1. mayorovp
              14.07.2017 16:59
              -1

              А в моем MVVM-мире firstName + ' ' + lastName — это множественный биндинг с форматированием.


            1. Avenger911
              15.07.2017 10:34
              +1

              Учитывая, сколько в мире разных способов записи полного имени, fullName = firstName + ' ' + familyName вполне может быть бизнес-логикой.


              А padStart, как мне кажется, больше всего в консольных скриптах для вывода каких-нибудь табличек востребован.


  1. QtRoS
    12.07.2017 22:12

    Хм, а почему возвращается массив, в котором ключ — строка, а не целочисленный индекс?

    const obj = ['e', 's', '8'];
    Object.entries(obj); // [['0', 'e'], ['1', 's'], ['2', '8']]
    

    И разве комментарий говорит истину — объект и массив это одно и то же?
    const obj = ['e', 's', '8']; // same as { 0: 'e', 1: 's', 2: '8' };
    


    1. RidgeA
      12.07.2017 22:58

      Можно сказать, что массив — это частный случай объекта.

      https://www.ecma-international.org/ecma-262/#sec-array-objects

      Ничто (кроме, пожалуй здравого смысла) не мешает сделать так:

         const obj = [];
         obj[0] = 0;
         obj[42] = 42;
      

      Хм, а почему возвращается массив, в котором ключ — строка, а не целочисленный индекс?

      выходит из того, что массив — частный случай объекта, а свойством объекта может быть только строка


      1. torbasow
        13.07.2017 11:01
        +2

        Однако

        typeof ['e', 's', '8'].indexOf("s") === "number"
        


    1. Avenger911
      13.07.2017 12:12

      Ключи объектов в JS являются строками (ну или символами Symbol), а всё остальное приводится к строкам. Поэтому логично, думаю, что методы Object возвращают ключи как строки.


      Более того, индексы массива не преобразуются к числам, и можно сделать arr['000'] = '000', не затрагивая arr[0]. Однако, indexOf этот элемент уже не найдёт. Получается, что методы массивов — как бы синтаксический сахар, отвечающий ожиданиям программиста о целочисленных индексах.


      И разве комментарий говорит истину — объект и массив это одно и то же?

      Не совсем, как минимум у массива есть ещё свойство length.


      1. mayorovp
        13.07.2017 12:28

        Надо различать элементы массива и его свойства. 0 и '0' — это элемент, а '000' иlength`` — это свойства.


        indexOf ищет только по элементам, а не по свойствам.


  1. sultan99
    13.07.2017 11:20

    Эх почему такие длинные и уродливые названия getOwnPropertyDescriptors?


    Ждал появления приватных методов и свойств в классах (но только без использования #) и объявления статистических свойств в классах. А вместо этого какие-то лишние запятые в функции и еще другого ненужного говна...


    1. Alternator
      13.07.2017 17:52

      Скажите пожалуйста, что за приватные методы/свойства с «использованием #»?


      1. sultan99
        13.07.2017 20:00

        Их еще не утвердили, какое-то время бурно обсуждали, специфику продвинули аж до stage-2.
        Тут можно почитать proposal по внесению данной фичи.


  1. MrGobus
    13.07.2017 12:45

    Поясните за «Паддинг», нафига как часть стандарта?


    1. RidgeA
      13.07.2017 12:46
      +1

      https://habrahabr.ru/post/280099/


  1. raveclassic
    13.07.2017 13:23
    -1

    Паддинги строк, getOwnPropertyDescriptors, запятые в аргументах…
    TC39, вы там блин угараете?


    1. justboris
      13.07.2017 13:27
      +2

      А как надо?


      Если бы они каждый год релизили столько же фич, как в ES6, то тогда бы вся работа встала, а все силы ушли на изучение, что же там нового в очередном ES-X завезли.


      1. raveclassic
        13.07.2017 13:34

        Не уверен, что нужно фанатично бросаться на изучение фич в ущерб работе. Тем более, что эта самая работа как-то и без этих фич работалась.
        Но по мере постепенного изучения, работа бы работалась быстрее и удобнее.
        Вон команда TS, что не новая версия, то подарок. А тут… больше сахара богу сахара.


        1. mayorovp
          13.07.2017 13:48

          Команде TS проще: они делают компилируемый язык и одновременно единственный же компилятор к нему.


          1. raveclassic
            13.07.2017 13:52

            Ну а TC39 совсем проще, они не делают ничего, кроме спеки.


            1. MaxKorz
              13.07.2017 15:04
              +1

              http://tc39wiki.calculist.org/about/people/
              большинство людей работающих над TC39 — люди из Google, Apple, Microsoft, Mozilla. То есть компании-разработчики браузеров сами разрабатывают стандарт. Что вас не устравиает?


              1. raveclassic
                13.07.2017 15:19

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


                1. mayorovp
                  13.07.2017 15:20
                  +2

                  И почему же запятые в аргументах вдруг стали хламом?


                  1. raveclassic
                    13.07.2017 15:24
                    +1

                    Потому-что по сравнению с existential operator, array comprehensions и многим, многим другим, trailing comma в аргументах — это хлам


                    1. mayorovp
                      13.07.2017 15:34
                      +2

                      Но это же не означает что они не нужны.


                      1. raveclassic
                        13.07.2017 15:42

                        Ну как сказать… У проблемы с запятыми ноги растут из объектов и массивов с построчным объявлением. Тот же гит сходит с ума. А функции? Часто ли вы пишите функции с таким количеством аргументов, чтобы разносить их по одному на строчку?


                        Между тем, existential operator заметно бы облегчил код, избавив от проверок через &&, if'ов и всяких велосипедов типа path. Но нет.


                        1. MaxKorz
                          13.07.2017 15:51

                          вы так говорите будто все что сделали в стандарте, который разрабатывали целый год — запятые у аргументов функции. А как же разделяемая память, атомарные операции и асинхронные функции? Они не важны? Если когда-нибудь в будущем добавят existential operator, то эта фича тоже будет казаться какой-то ненужной мелочью по сравнению с другими изменениями (например, декораторами)


                          1. raveclassic
                            13.07.2017 16:04
                            +1

                            А вы посмотрите на мой коммент в начале этой ветки, там про остальное ничего не сказано, упомянут только хлам.


                        1. justboris
                          13.07.2017 16:12
                          +2

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


                          Поэтому запятую в аргументы нам добавили, видимо было несложно, а optional chaining — пока на stage 1


                        1. m0sk1t
                          13.07.2017 17:57

                          ну допустим так:

                          constructor(
                          	public navCtrl: NavController,
                          	public navParams: NavParams,
                          	public alertCtrl: AlertController,
                          ) {}
                          

                          как пример…
                          P.S. Да, я в курсе что это TS, просто кусок кода оказавшийся под рукой был именно на нём


                          1. raveclassic
                            14.07.2017 00:57
                            +3

                            Да, я с вами полностью согласен, так как сам большую часть времени пишу на TS и именно в таком виде.


                            Но тут интересный момент. Если вы вводите новый аргумент в функцию, то явно не просто так, вы так же меняете и ее тело. Так какая тогда разница, если вы коммитом зацепили одну строчку с предыдущим аргументом?


                            Я бы хотел еще раз заострить внимание на том, что я не против комитета TC39, как тут многие подумали. Я против некоторых (увы, их много) их решений.


                            Самое больное — это синтаксис es6-модулей, когда вы пишете сначала import {} from, потом имя модуля (или путь), потом возвращаетесь в фигурные скобки, и только тогда вам IDE/редактор сможет помочь и подсказать, что же там в этом модуле находится. Я не спорю, может кому-то в кайф читать доки модуля и руками писать все это дело, но мне кажется, что это все не относится к решению задачи, а лишь создает вокруг себя очень много шума.


                            1. mayorovp
                              14.07.2017 09:18
                              -1

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


                              Когда я на C# формирую XML через Linq2Xml — постоянно не хватает возможности поставить эту самую запятую в конце.


                              1. darkdaskin
                                14.07.2017 16:54
                                +1

                                В LINQ2XML удобно писать так:


                                new XElement("foo",
                                    new XAttribute("bar", 1),
                                    new XAttribute("baz", 2),
                                    null);

                                Все null в списке аргументов игнорируются, что позволяет у всех значимых аргументов иметь запятую в конце.


                                Также эта особенность позволяет удобно указывать опциональные элементы:


                                
                                new XElement("foo",
                                    condition ? new XElement("bar") : null,
                                    null);


  1. Enmar
    13.07.2017 18:41

    круто :-)
    Заюзаем в продакшене скоро.


  1. sultan99
    14.07.2017 07:04

    Думаю лучше было бы если стандартизовали не язык (ES/JS), а входной бинарный код, и вся специфика крутилась бы вокруг этих команд. Синтаксис (семантика) вышел бы на новый слой, то есть это мог бы любой другой язык (Python, Ruby и прочие сексуальные языки, в том числе и сам JS), и отдельные либы/компиляторы подгоняли бы исходники под бинарник, который понимают браузеры. И тут открылись бы новые горизонты для выбора языка, и даже изобретай собственный главное, чтобы твой язык мог скомпилить бинарник под общую "web" специфику. Причем данный подход можно реализовать поэтапно, поддержка текущего JS и плюс так скажем "бинарных файлов", существующие сайты на JS, работали также без как и раньше, но а новые потихоньку стали бы смещать JS.


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


    1. rumkin
      15.07.2017 03:44

      WebAssembly чем не устраивает-то?


      1. madkite
        18.07.2017 20:23

        Наверно тем, что очень низкоуровневый — нету сборщика мусора, оперировать с dom-ом сложно, т.к. для надо этого надо вызывать JavaScript API, при этои объекты по ссылке не передаются, надо каждый раз их копировать. В итоге сфера его применения не особо пока пересекается с типичным применением JavaScript.



  1. rumkin
    19.07.2017 15:00

    … нету сборщика мусора, оперировать с dom-ом сложно, т.к. для надо этого надо вызывать JavaScript API...

    Сборщик мусора еще не успели спроектировать, о нем просто рано еще говорить, но он точно будет. При этом уже можно использовать Rust, ему не нужен gc. Для операций с DOM, вполне хватает JS API, со временем, думаю ситуация тоже изменится, но уже сейчас все что вы делаете с DOM на JS можно сделать и на WebAssembly + немного JS. Так что мне все же не понятно, что имеет в виду sultan99.


    1. madkite
      20.07.2017 16:20

      Оперировать с DOM через JS API то можно, но оно не очень удобно, т.к. любые стректуры надо копировать — по ссылке они не передаются, т.о. это влияет на производительность. А для типичных JavaScript-приложений, выполненных как SPA, операции с DOM — это основное, что на каждом чихе выполняется. Конечно, есть задачи, где WebAssembly хорошо подходит, но пока оно не очень универсально и даже не планирует заменить JavaScript, а позиционируется как дополнение.