Сова пишет…
3.16K subscribers
344 photos
37 videos
5 files
414 links
Frontend Senior Fullstack Backend Lead и прочие слова.
Изучаю самые современные технологии.
Обучаю разработчиков как стать сильнее — https://frontend.vision.

По коллаборациям и сотрудничеству пишите в сообщения канала!
Download Telegram
Default Exports in JavaScript Modules Are Terrible

Ещё одна статья, в которой рассказывается, почему не стоит использовать export default.

В кратце:
- Автокомплит не подсказывает, что у модуля есть export default, если вы начали делать импорт через { }
- То, что экспортируется через export default может быть импортировано под любым именем. Это создает сразу несколько проблем: возможность криво назвать, то что импортируется; возможность назвать по-разному одну и ту же сущность в разных файлах; возможность неконсистентного именования при импортах из пакетов

Если вам нужен аргумент против использования export default в своих проектах - посмотрите эту статью.

В целом у export default есть боле мене адекватные места для применения. Например, библиотеки. import React from 'react' - это как раз случай, когда export default не делает хуже. Хотя и с именоваными экспортами было бы нормально.

Лично я предпочитаю забанить export default в проектах на уровне линтера. Отсутствие адекватного автокомплита и возможность накосячить с именованием слишком сильно бьют по DX в проекте

https://www.lloydatkinson.net/posts/2022/default-exports-in-javascript-modules-are-terrible/

#development #javascript #modules
👍27👎5
Ecma International approves ECMAScript 2025: What’s new?

25 июня зафиксировали стандарт ECMAScript 2025.

Что зафиксировали: импорт-атрибуты (нужны для JSON-модулей), хелперы для итераторов, новые методы Set, немного улучшили RegExp, добавили Promise.try и поддержки 16-битных чисел с плавающей точкой

Import attributes
Добавили в язык возможность импортировать не JS код. Для этого понадобилось добавлять синтаксис, который бы объяснял движку или рантайму, что сейчас будет импорчено
import configData1 from './config-data.json' with { type: 'json' };

// Dynamic import
const configData2 = await import(
'./config-data.json', { with: { type: 'json' } }
);


Хелперы для итераторов
Для массивов есть удобные методы, а для итераторов - нет. Решили исправить эту несправедливость и перенесли часть методов на итераторы
const arr = ['a', '', 'b', '', 'c', '', 'd', '', 'e'];
assert.deepEqual(
arr.values() // creates an iterator
.filter(x => x.length > 0)
.drop(1)
.take(3)
.map(x => `=${x}=`)
.toArray()
,
['=b=', '=c=', '=d=']
);


Адаптированные для итератора методы
- iterator.filter(filterFn)
- iterator.map(mapFn)
- iterator.flatMap(mapFn)
- iterator.some(fn)
- iterator.every(fn)
- iterator.find(fn)
- iterator.reduce(reducer, initialValue?)
- iterator.forEach(fn)

Также сделали аналоги slice
- iterator.drop(limit) возвращает новый итератор без первых limit значений (по сути slice(limit))
- iterator.take(limit) возвращает новый итератор с первыми limit значениями (по сути slice(0, limit))

Еще сделали удобный метод для преобразования итератора в массив iterator.toArray()

Новые методы Set
- Создание нового сета из двух существующих:
- Set.prototype.intersection(other) - пересечение - только те значения, которые есть в обоих наборах
- Set.prototype.union(other) - объединение - значение из обоих наборов
- Set.prototype.difference(other) - позволяет достать множество, которое получится если из множества А убрать все элементы множества Б
- Set.prototype.symmetricDifference(other) - позволяет достать множество, которое содержит элементы которые входят только в одно из множеств
- Определение отношения наборов:
- Set.prototype.isSubsetOf(other) - является ли набор А - подмножеством набора Б
- Set.prototype.isSupersetOf(other) является ли набор А - надмножеством набора Б
- Set.prototype.isDisjointFrom(other) - возвращает true, если у множеств нет пересечений

assert.deepEqual(
new Set(['a', 'b', 'c']).union(new Set(['b', 'c', 'd'])),
new Set(['a', 'b', 'c', 'd'])
);
assert.deepEqual(
new Set(['a', 'b', 'c']).intersection(new Set(['b', 'c', 'd'])),
new Set(['b', 'c'])
);
assert.deepEqual(
new Set(['a', 'b']).isSubsetOf(new Set(['a', 'b', 'c'])),
true
);
assert.deepEqual(
new Set(['a', 'b', 'c']).isSupersetOf(new Set(['a', 'b'])),
true
);



Улучшения RegExp
RegExp.escape(text) позволяет вставить текст в RegExp и быть уверенным, что вставленный текст не сломает RegExp

 const regExp = new RegExp(
`(?<!“)${RegExp.escape(text)}(?!”)`,
'gu'
);


Флаги теперь можно применять не ко всему RegExp, а к отдельным группам
 /^x(?i:HELLO)x$/.test('xHELLOx') // true


Можно использовать одинаковые имена для групп
const RE = /(?<chars>a+)|(?<chars>b+)/v;


Promise.try
Promise.try немного упрощает создание промиса с синхронными функциями
 return Promise.try(() => {
const value = syncFuncMightThrow();
return asyncFunc(value);
});


Если функция syncFuncMightThrow бросит исключение, то Promise.try вернет реджектнутый промис.

Работа с 16-битными числами
По дефолту числа в JS представлены 64-битными числами с плавающей точкой. Но есть кейсы, когда необходимо вести все вычисления в 16 или 32-битных числах. В JS добавили разные хелперы для работы с такими числами, например Math.f16round делает округление в пространстве 16-битных чисел

console.log(Math.f16round(2**16)) // Infinity

console.log(2**16) // 65536


https://2ality.com/2025/06/ecmascript-2025.html

#development #javascript #ecmascript #releaseNotes
🔥3342👍1