Pull to refresh

Comments 104

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

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

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

Да (и такое бы можно было организовать, если бы WeakMap/WeakSet можно было бы проитерировать).
В первой таблице поддержки (для функций паддинга) указана версия IE 15. Разве такая вообще существует?
Вероятно имеется в виду Edge, но он в той же таблице указан рядом как отдельный браузер.
этот баг, вероятно, остался с тех времен, когда ИЕ что-то поддерживал.
Лишние запятые в списке параметров функции и вызове

WTF…

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


let someArray = [
  longElement1,
  longElement2,
  longElement3,
];

someFunction(
  longParam1,
  longParam2,
  longParam3,
)

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

UFO just landed and posted this here

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


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

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

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

Да я, в принципе, сразу так и понял, так как это единственная разумная причина такое добавлять. Но что-то внутри меня перевернулось)
Куда менее прятный вот такой момент я нашел в документации мозиллы по поводу 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;
}

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


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

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

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

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

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

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

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


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

Согласен, забыл про этот момент.
Вот если бы синтаксис был примерно такой:
async function add1(x) {
  var a = resolveAfter2Seconds(20);
  var b = resolveAfter2Seconds(30);
  return await(x + a + b);
}

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

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

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


async function someAction(x) {
  const a = someAsyncOperation();

  // куча разного другого кода

  await a;
}

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

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

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

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

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


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

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

Поддерживаю. WTF? Культура кода, нет не слушал. Мы сделаем стандарт который будет разрешать что угодно. Хотите лишнюю запятую? Пожалуйста. Лишнюю закрывающую скобку? Не проблема? Чехарду с кавычками и без них, не вопрос. :) Пусть ребята которые занимаются реализацией нашего стандарта сами мозг ломают как всю эту магию реализовать. :)
Строгость нужно только тогда, когда отсутствие её может вызвать непредсказуемость.
В некоторых стайлгайдах «лишняя» запятая является обязательной, если список разделяется на несколько строк. Это, в частности, позволяет обходиться одной строчкой diff на один добавленный в конец списка или удаленный с него. Вот это культура кода.
UFO just landed and posted this here
В .NET C# тоже такая фича с первой версии доступна.
В C# такая фича доступна только для массивов и для инициализации объектов, а в питоне и для параметров функций тоже.
ещё один способ асинхронного получения данных… когда уже найдётся «идеал»

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

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

image

str.padStart(targetLength [, padString]);
Наконец спасет многие библиотеки от странных зависимостей, аля npm left-pad или pad-left.
Если только на бэкенде — клиентский код все равно придется еще несколько лет обмазывать полифиллами.
Frontend требует особые жертв и обрядов.
UFO just landed and posted this here
UFO just landed and posted this here

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

А объясните кто-нибудь как работает эта фича:
helper`ES ${esth} is `;

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

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

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

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


add(1,2,3,)

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


add(
    1,
    2,
    3,
)

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

Ещё можно не писать 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: Проверил: нет, так нельзя :-(

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

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

Ну, например, форматировать время удобно. «01:05»
так даже немного короче:
('0'+1).slice(-2)
'1'.padStart(2, '0')
А разве совать верстку в логику не дурной тон?

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


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


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

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

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

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


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

Хм, а почему возвращается массив, в котором ключ — строка, а не целочисленный индекс?
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' };
Можно сказать, что массив — это частный случай объекта.

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

Ничто (кроме, пожалуй здравого смысла) не мешает сделать так:
   const obj = [];
   obj[0] = 0;
   obj[42] = 42;

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

выходит из того, что массив — частный случай объекта, а свойством объекта может быть только строка
Однако
typeof ['e', 's', '8'].indexOf("s") === "number"

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


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


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

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

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


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

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


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

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

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

А как надо?


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

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

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

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

UFO just landed and posted this here

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

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

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

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

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


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

UFO just landed and posted this here

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

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


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

ну допустим так:
constructor(
	public navCtrl: NavController,
	public navParams: NavParams,
	public alertCtrl: AlertController,
) {}

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

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


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


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


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

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


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

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


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

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


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



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

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


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

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

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

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

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

Так а зачем копировать структуры или указывать ссылки на них? Достаточно пробросить методы для получения нужных значений.

Sign up to leave a comment.

Articles