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'
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']
Метод
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']]
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
// }
Данные дескрипторов очень важны для таких продвинутых фич, как декораторы.
Лишние запятые в списке параметров функции и вызове
Возможность указать лишние запятые в параметрах функции позволяет не получать ошибку (
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
.Разделяемая память и атомарные операции
Когда память разделяемая, множество потоков может читать и писать те же данные в памяти. Атомарные операции позволяют убедиться, что предсказуемые значения записаны и прочитаны, что операции завершены до начала следующих операций. В этом разделе представлен новый конструктор
SharedArrayBuffer
и объект Atomics
со статическими методами.Объект
Atomics
– это набор статических методов как Math
, так что мы не сможем вызвать его конструктор. Примеры статических методов этого объекта:- add / sub — добавление / вычитание значения из значения в указанной позиции
- and / or / xor? —? побитовое «И» / побитовое «ИЛИ» / исключающее «ИЛИ»
- load ?—? получение значения в указанной позиции
И один момент на следующий год в 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.
Заключение
JavaScript уже в продакшене, но всегда обновляется. Процесс принятия новых возможностей в спецификацию очень организован и устойчив. На последнем этапе этот функционал подтверждается комитетом TC39 и реализуется основными разработчиками. Большинство из них уже реализовано в языке Typescript, браузерах или разных полифиллах, так что вы можете пробовать их уже сейчас.
Комментарии (103)
DreamChild
12.07.2017 12:20+1В первой таблице поддержки (для функций паддинга) указана версия IE 15. Разве такая вообще существует?
Вероятно имеется в виду Edge, но он в той же таблице указан рядом как отдельный браузер.
Leg3nd
12.07.2017 12:20+4Лишние запятые в списке параметров функции и вызове
WTF…Avenger911
12.07.2017 12:39+6очевидно, чтобы при записи в столбик окончания строк не отличались:
let someArray = [ longElement1, longElement2, longElement3, ]; someFunction( longParam1, longParam2, longParam3, )
rayz_razko
12.07.2017 12:49И это теперь чатсь спецификации? WTF?
Avenger911
12.07.2017 13:09+9Ну а почему бы и нет, если в литералах массивов и объектов это уже есть? И частью чего ещё это должно быть?
Alexeyco
12.07.2017 14:50-5Есть, но ESLint базово требует убирать висячие запятые в объектах.
justboris
12.07.2017 15:31+10Eslint настраиваемая штука, по умолчанию он ничего не требует.
Если вы возьмете например стайлгайд от AirBnB, то там висячие запятые как раз-таки наоборот, требуются всегда
comerc
13.07.2017 00:04А если прикрутить Prettier, то оно вообще не парит.
justboris
13.07.2017 11:18Да, но там эта опция тоже за флагом
--trailing-comma=all
. По дефолту конечные запятые не ставятся/убираютсяcomerc
13.07.2017 22:01Я сейчас на PHP (по требованию заказчика) сочиняю API. После 5-ти летней паузы. Вот откуда ноги растут с этими запятыми!
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; }
justboris
13.07.2017 11:49+1О таком поведении можно догадаться. В первом случае мы запускаем операцию после
await
, а во-втором случае мы сначала запускаем обе операции, а потом уже ставим await на них.
А если все равно неочевидно получается, то всегда можно переписать фрагмент кода на ручные вызовы
.then()
.Leg3nd
13.07.2017 12:14+1Для меня не очевидно потому что await означает, что мы ждем окончания асинхронной операции при его наличии. И логично что, если два await явно указано, то и ожидание должно происходить два раза. А чтобы дождаться нескольких результатов асинхронных функций как бы существует Pormise.all(). Он как раз явно и указывает на этот процесс.
Понятно, что во втором примере с использованием Promise.all() больше кода получится. Но с другой стороны, во втором примере на параллельность получения результатов указывает только то, что await'ы находятся в выражении, которое возвращается из aync функции и больше ничего. Такое легко забыть, пропусть… короче не очевидно как по мне.faiwer
13.07.2017 12:21+1Поверьте, после пары дней активного использования
async-await
это всё будет не только очевидно, но и доведено до автоматизма. Особенно если до этого был опыт работы сPromise
-ми. Те же генераторы куда сложнее для понимания, имхо.Leg3nd
13.07.2017 12:53+1Вот по поводу генераторов — как то не нашел для себя полезного применения им в повседневных задачах…
faiwer
13.07.2017 13:53Ими удобно реализовывать то, для чего они предназначены — протоколы итерации каких-либо коллекций. А это бывает востребованным при написании библиотек. Какие-нибудь там парсеры, конвертеры и пр. Где есть свои типы коллекций и итераторов по ним. В общем штука достаточно специфичная.
raveclassic
13.07.2017 13:58Мне кажется, что основной фишкой является отменяемость. Потом идет тестируемость.
mayorovp
13.07.2017 12:22-1Вот именно,
await
означает что мы ждем окончания асинхронной операции — и ничего не говорит о начале этой операции.
Параллельность ожидания случилась не потому что
await
находятся в выражении, а потому что между вызовамиresolveAfter2Seconds
нет вызоваawait
.
Leg3nd
13.07.2017 12:20Вот если бы синтаксис был примерно такой:
async function add1(x) { var a = resolveAfter2Seconds(20); var b = resolveAfter2Seconds(30); return await(x + a + b); }
Вот тогда бы я согласился с Вами, что можно догадаться :)faiwer
13.07.2017 12:24Предложенный вами синтаксис нереален, т.к. нотация
methodName()
запускаетmethodName
сразу, а не по истечению какого-либо времени. К тому жеawait
-ить можно всё что угодно, что умеет метод.then
, а не толькоasync method
-ы.
justboris
13.07.2017 12:31Скорее вот так
async function someAction(x) { const a = someAsyncOperation(); // куча разного другого кода await a; }
по вашей логике
someAsyncOperation
должна не выполняться сразу, а ждет, пока ее не за-await-ят. А что будет, если await не сделают никогда? Операция не выполнится вообще?Leg3nd
13.07.2017 12:40+2Да, выше уже мне указали на мой промах. Я почему-то подзабыл, что вызов асинхронной фунции не только возвращает промис, но и запускает выполнение самой функции.
faiwer
13.07.2017 13:55что вызов асинхронной фунции
помимо прочего это может быть и не асинхронная функция, а самая обыкновенная. И эта функция даже не обязательно должна возвращать promise, хотя это уже несколько странно :)
Avenger911
13.07.2017 12:21Ага, значит несколько
await
в одном выражении ожидаются параллельно. Важный момент, как мне кажется, потому что независимые вызовы нет смысла выполнять поочерёдно. Спасибо за информацию!mayorovp
13.07.2017 12:23Нет. Операторы
await
всегда ждут последовательно!
А вот сами асинхронные операции могут без особых проблем идти параллельно. Надо просто не путать вызов асинхронной функции и ожидание его результата.
DexterHD
12.07.2017 17:39-6Поддерживаю. WTF? Культура кода, нет не слушал. Мы сделаем стандарт который будет разрешать что угодно. Хотите лишнюю запятую? Пожалуйста. Лишнюю закрывающую скобку? Не проблема? Чехарду с кавычками и без них, не вопрос. :) Пусть ребята которые занимаются реализацией нашего стандарта сами мозг ломают как всю эту магию реализовать. :)
bro-dev
12.07.2017 18:02+5Строгость нужно только тогда, когда отсутствие её может вызвать непредсказуемость.
VolCh
12.07.2017 21:57+4В некоторых стайлгайдах «лишняя» запятая является обязательной, если список разделяется на несколько строк. Это, в частности, позволяет обходиться одной строчкой diff на один добавленный в конец списка или удаленный с него. Вот это культура кода.
Laney1
12.07.2017 19:53+5не понимаю массового горения по поводу этой фичи. Например, она давно есть в питоне (откуда видимо и взята), никому там не мешает и широко используется
reilag
12.07.2017 12:57+8Процесс принятия новых возможностей в спецификацию очень организован и устойчив. На последнем этапе этот функционал подтверждается комитетом TC39 и реализуется основными разработчиками.
MaxKorz
12.07.2017 13:36Приятно, что большинство этих функций уже реализовано и используется в продакшене тем или иным путем:
padStart, padEnd, Object.values и Object.entries уже давно являются частью core-js
Асинхронные функции реализуются с помощью babel/typescript.
То есть последние фичи можно использовать уже сейчас, а не ждать пару лет, пока большинство юзеров обновятся.RifleR
12.07.2017 14:04+1Ну правильно, это обычный путь в стандарт — сначала используют стороннюю библиотеку для какой-то фичи, потом кто-то предлагает фичу в черновик стандарта, потом используют babel, а уже после добавления в стандарт отключают транпиляцию данной фичи — нативное использование… PROFIT!
inoyakaigor
12.07.2017 14:22А объясните кто-нибудь как работает эта фича:
helper`ES ${esth} is `;
Почему «склеивая» руками имя функции и шаблонную строку мы, получается, вызываем эту функцию с этой строкой в качестве параметра?
samizdam
12.07.2017 17:18Интересно, что все описываемые в публикации новшества, реализованы только в Firefox.
Почему-то думал что Chrome развивается не менее динамично в этом направлении, ан нет.RifleR
12.07.2017 18:25Вы не совсем правы, на самом деле сейчас все фичи ES2017 реализованы в Chrome, Firefox, Safari. Где-то в стабильной версии, где-то в бета-версии, где-то что-то пока под флагом. Но реализованы. Сейчас производители развивают браузеры в общем-то очень динамично. Чуть отстает только Edge, но и то не сильно.
samsdemon
12.07.2017 23:11+1Я раньше тоже на это смотрел, но потом узнал, что в сафари/вебките всё реализовано на 100% (или 99%), но какая разница, если в последнее время модно даже среди менеджеров просить делать progressive enhancement через Chrome, мол, если там оно работает, то добавьте плз чего-нибудь, всё равно половина пользователей через хром сидят. При этом если раньше это было только по CSS заметно (типа http://www.hongkiat.com/blog/css-image-set/, или ещё чего), то теперь появляются всякие Web Bluetooth и прочие, что не может не радовать
rumkin
12.07.2017 17:39+1Не "лишние", а "висячие" запятые и нужны они не для записи вида
add(1,2,3,)
а для записей вида:
add( 1, 2, 3, )
… когда аргументов много и они длинные. Это нужно, чтобы со строками было удобнее работать. При перемещении последней сроки вверх нет необходиомсти изменять окончания строк.
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: Проверил: нет, так нельзя :-(
vtvz_ru
12.07.2017 21:15+5Это особенно актуально в Git. Если много аргументов и ты добавляешь еще один, то на выходе получается одна измененная строка. В старом случае, их было две: одна, где ты поставил запятую, и новая. Некий эстетический дискомфорт от подобного я испытываю, редактируя JSON файлы, где в конце ну никак нельзя оставить запятую, а запихать данные в середину не получается.
dmitry_dvm
12.07.2017 19:15-5padStart попахивает выравниванием пробелами в ворде. Это реально нужно?
TheShock
12.07.2017 21:30+3Ну, например, форматировать время удобно. «01:05»
dmitry_dvm
13.07.2017 21:15А разве совать верстку в логику не дурной тон?
justboris
13.07.2017 23:04+1А где здесь логика?
Например сложение
firstName + ' ' + lastName
— это же верстка?
Тогда отчего
value.padStart(2, '0')
внезапно оказывается логикой?dmitry_dvm
14.07.2017 16:45-1В моем MVVM-мире firstName + ' ' + lastName — это как раз таки логика в верстке, ибо такие вещи делаются через байндинг полей модели к элементам верстки. Но это у меня в MVVM. В фронтенде, видимо, многое иначе.
Кстати насчет камента выше про реакт. Уверен, следующий реакт будет именно с отделением кода от верстки, всё идет по кругу. Раньше тоже лепили всё в один хтмл, потом разделили, а сейчас опять слепили. Значит скоро опять разделят.mayorovp
14.07.2017 16:59-1А в моем MVVM-мире
firstName + ' ' + lastName
— это множественный биндинг с форматированием.
Avenger911
15.07.2017 10:34+1Учитывая, сколько в мире разных способов записи полного имени,
fullName = firstName + ' ' + familyName
вполне может быть бизнес-логикой.
А
padStart
, как мне кажется, больше всего в консольных скриптах для вывода каких-нибудь табличек востребован.
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' };
RidgeA
12.07.2017 22:58Можно сказать, что массив — это частный случай объекта.
https://www.ecma-international.org/ecma-262/#sec-array-objects
Ничто (кроме, пожалуй здравого смысла) не мешает сделать так:
const obj = []; obj[0] = 0; obj[42] = 42;
Хм, а почему возвращается массив, в котором ключ — строка, а не целочисленный индекс?
выходит из того, что массив — частный случай объекта, а свойством объекта может быть только строка
Avenger911
13.07.2017 12:12Ключи объектов в JS являются строками (ну или символами
Symbol
), а всё остальное приводится к строкам. Поэтому логично, думаю, что методыObject
возвращают ключи как строки.
Более того, индексы массива не преобразуются к числам, и можно сделать
arr['000'] = '000'
, не затрагиваяarr[0]
. Однако,indexOf
этот элемент уже не найдёт. Получается, что методы массивов — как бы синтаксический сахар, отвечающий ожиданиям программиста о целочисленных индексах.
И разве комментарий говорит истину — объект и массив это одно и то же?
Не совсем, как минимум у массива есть ещё свойство
length
.mayorovp
13.07.2017 12:28Надо различать элементы массива и его свойства.
0
и'0'
— это элемент, а'000' и
length`` — это свойства.
indexOf
ищет только по элементам, а не по свойствам.
sultan99
13.07.2017 11:20Эх почему такие длинные и уродливые названия
getOwnPropertyDescriptors
?
Ждал появления приватных методов и свойств в классах (но только без использования
#
) и объявления статистических свойств в классах. А вместо этого какие-то лишние запятые в функции и еще другого ненужного говна...Alternator
13.07.2017 17:52Скажите пожалуйста, что за приватные методы/свойства с «использованием #»?
sultan99
13.07.2017 20:00Их еще не утвердили, какое-то время бурно обсуждали, специфику продвинули аж до
stage-2
.
Тут можно почитать proposal по внесению данной фичи.
raveclassic
13.07.2017 13:23-1Паддинги строк, getOwnPropertyDescriptors, запятые в аргументах…
TC39, вы там блин угараете?justboris
13.07.2017 13:27+2А как надо?
Если бы они каждый год релизили столько же фич, как в ES6, то тогда бы вся работа встала, а все силы ушли на изучение, что же там нового в очередном ES-X завезли.
raveclassic
13.07.2017 13:34Не уверен, что нужно фанатично бросаться на изучение фич в ущерб работе. Тем более, что эта самая работа как-то и без этих фич работалась.
Но по мере постепенного изучения, работа бы работалась быстрее и удобнее.
Вон команда TS, что не новая версия, то подарок. А тут… больше сахара богу сахара.mayorovp
13.07.2017 13:48Команде TS проще: они делают компилируемый язык и одновременно единственный же компилятор к нему.
raveclassic
13.07.2017 13:52Ну а TC39 совсем проще, они не делают ничего, кроме спеки.
MaxKorz
13.07.2017 15:04+1http://tc39wiki.calculist.org/about/people/
большинство людей работающих над TC39 — люди из Google, Apple, Microsoft, Mozilla. То есть компании-разработчики браузеров сами разрабатывают стандарт. Что вас не устравиает?raveclassic
13.07.2017 15:19Кажется, меня не поняли. Меня полностью устраивает что стандартом занимаются далеко не последние люди. Не устраивает, что вместо решения реальных проблем, в стандарт попадает всякий хлам типа запятых в аргументах.
mayorovp
13.07.2017 15:20+2И почему же запятые в аргументах вдруг стали хламом?
raveclassic
13.07.2017 15:24+1Потому-что по сравнению с existential operator, array comprehensions и многим, многим другим, trailing comma в аргументах — это хлам
mayorovp
13.07.2017 15:34+2Но это же не означает что они не нужны.
raveclassic
13.07.2017 15:42Ну как сказать… У проблемы с запятыми ноги растут из объектов и массивов с построчным объявлением. Тот же гит сходит с ума. А функции? Часто ли вы пишите функции с таким количеством аргументов, чтобы разносить их по одному на строчку?
Между тем, existential operator заметно бы облегчил код, избавив от проверок через &&, if'ов и всяких велосипедов типа path. Но нет.
MaxKorz
13.07.2017 15:51вы так говорите будто все что сделали в стандарте, который разрабатывали целый год — запятые у аргументов функции. А как же разделяемая память, атомарные операции и асинхронные функции? Они не важны? Если когда-нибудь в будущем добавят existential operator, то эта фича тоже будет казаться какой-то ненужной мелочью по сравнению с другими изменениями (например, декораторами)
raveclassic
13.07.2017 16:04+1А вы посмотрите на мой коммент в начале этой ветки, там про остальное ничего не сказано, упомянут только хлам.
justboris
13.07.2017 16:12+2Ну так и работа над разными улучшениями идет, просто пока не завершена. Слишком много неоднозначностей, которые нужно прояснить и утвердить в спеке.
Поэтому запятую в аргументы нам добавили, видимо было несложно, а optional chaining — пока на stage 1
m0sk1t
13.07.2017 17:57ну допустим так:
constructor( public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController, ) {}
как пример…
P.S. Да, я в курсе что это TS, просто кусок кода оказавшийся под рукой был именно на нёмraveclassic
14.07.2017 00:57+3Да, я с вами полностью согласен, так как сам большую часть времени пишу на TS и именно в таком виде.
Но тут интересный момент. Если вы вводите новый аргумент в функцию, то явно не просто так, вы так же меняете и ее тело. Так какая тогда разница, если вы коммитом зацепили одну строчку с предыдущим аргументом?
Я бы хотел еще раз заострить внимание на том, что я не против комитета TC39, как тут многие подумали. Я против некоторых (увы, их много) их решений.
Самое больное — это синтаксис es6-модулей, когда вы пишете сначала
import {} from
, потом имя модуля (или путь), потом возвращаетесь в фигурные скобки, и только тогда вам IDE/редактор сможет помочь и подсказать, что же там в этом модуле находится. Я не спорю, может кому-то в кайф читать доки модуля и руками писать все это дело, но мне кажется, что это все не относится к решению задачи, а лишь создает вокруг себя очень много шума.mayorovp
14.07.2017 09:18-1Скорее, этот синтаксис нужен не столько для объявлений функций, сколько для вызовов функций с произвольным числом аргументов.
Когда я на C# формирую XML через Linq2Xml — постоянно не хватает возможности поставить эту самую запятую в конце.
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);
sultan99
14.07.2017 07:04Думаю лучше было бы если стандартизовали не язык (ES/JS), а входной бинарный код, и вся специфика крутилась бы вокруг этих команд. Синтаксис (семантика) вышел бы на новый слой, то есть это мог бы любой другой язык (Python, Ruby и прочие сексуальные языки, в том числе и сам JS), и отдельные либы/компиляторы подгоняли бы исходники под бинарник, который понимают браузеры. И тут открылись бы новые горизонты для выбора языка, и даже изобретай собственный главное, чтобы твой язык мог скомпилить бинарник под общую "web" специфику. Причем данный подход можно реализовать поэтапно, поддержка текущего JS и плюс так скажем "бинарных файлов", существующие сайты на JS, работали также без как и раньше, но а новые потихоньку стали бы смещать JS.
Лично сейчас JS мой основной язык на котором пишу код ежедневно и мне он очень нравится, но некоторые определенные места в языке явно указывают, что авторы где-то залажали при проектирования языка.
rumkin
15.07.2017 03:44WebAssembly чем не устраивает-то?
madkite
18.07.2017 20:23Наверно тем, что очень низкоуровневый — нету сборщика мусора, оперировать с dom-ом сложно, т.к. для надо этого надо вызывать JavaScript API, при этои объекты по ссылке не передаются, надо каждый раз их копировать. В итоге сфера его применения не особо пока пересекается с типичным применением JavaScript.
rumkin
19.07.2017 15:00… нету сборщика мусора, оперировать с dom-ом сложно, т.к. для надо этого надо вызывать JavaScript API...
Сборщик мусора еще не успели спроектировать, о нем просто рано еще говорить, но он точно будет. При этом уже можно использовать Rust, ему не нужен gc. Для операций с DOM, вполне хватает JS API, со временем, думаю ситуация тоже изменится, но уже сейчас все что вы делаете с DOM на JS можно сделать и на WebAssembly + немного JS. Так что мне все же не понятно, что имеет в виду sultan99.
madkite
20.07.2017 16:20Оперировать с DOM через JS API то можно, но оно не очень удобно, т.к. любые стректуры надо копировать — по ссылке они не передаются, т.о. это влияет на производительность. А для типичных JavaScript-приложений, выполненных как SPA, операции с DOM — это основное, что на каждом чихе выполняется. Конечно, есть задачи, где WebAssembly хорошо подходит, но пока оно не очень универсально и даже не планирует заменить JavaScript, а позиционируется как дополнение.
domix32
Не очень понял почему версии браузеров для Object.getOwnPropertyDescriptors такие маленькие. Оно с тех самых пор существовало, но не было частью никакого стандарта?
mannaro
Да, и таких фич много.
theTeacherOfEnglish
В последнее время в стандарт просто входят часто используемые фичи из
1. браузеров
2. из сторонних библиотек, типа JQuery или Lodash
И это в целом круто )