
1. Получение уникальных значений массива
В JavaScript сформировать массив, содержащий лишь уникальные значения из другого массива, вероятно, проще, чем вы думаете:
var j = [...new Set([1, 2, 3, 3])]
// [1, 2, 3]
Мне нравится то, как эту задачу можно решить, совместно используя оператор
...
и тип данных Set
.2. Массивы и логические значения
Вам когда-нибудь нужно было убрать из массива значения, приведение которых к логическому типу даёт
false
? Например, это такие значения, как 0
, undefined
, null
, false
. Возможно, вы не знали, что для того, чтобы это сделать, можно поступить так:myArray
.map(item => {
// ...
})
// Избавляемся от ненужных значений
.filter(Boolean);
Как видите, для того, чтобы избавиться от всех подобных значений, достаточно передать
Boolean
методу массивов .filter()
.3. Создание по-настоящему пустых объектов
Уверен в том, что вы можете создать объект, который кажется пустым, воспользовавшись синтаксисом объектного литерала:
{}
. Но такому объекту будет назначен прототип (__proto__
), у него будет метод hasOwnProperty()
и другие методы объектов. Для того чтобы создать по-настоящему пустой объект, который можно, например, использовать в качестве «словаря», можно поступить так:let dict = Object.create(null);
// dict.__proto__ === "undefined"
// У объекта нет никаких свойств до тех пор, пока вы их в явном виде не добавите к нему
В объекте, созданном таким способом, нет свойств и методов, которые не добавлены в него самим программистом.
4. Слияние объектов
Тем, кто пишет на JavaScript, всегда было нужно создавать такие объекты, которые включали бы в себя содержимое других объектов. Особенно актуальной эта задача стала тогда, когда в JavaScript появились классы, тогда, когда программистам приходится работать с чем-то вроде программных представлений виджетов. Вот как создать новый объект на основе нескольких других объектов:
const person = { name: 'David Walsh', gender: 'Male' };
const tools = { computer: 'Mac', editor: 'Atom' };
const attributes = { handsomeness: 'Extreme', hair: 'Brown', eyes: 'Blue' };
const summary = {...person, ...tools, ...attributes};
/*
Object {
"computer": "Mac",
"editor": "Atom",
"eyes": "Blue",
"gender": "Male",
"hair": "Brown",
"handsomeness": "Extreme",
"name": "David Walsh",
}
*/
Оператор
...
значительно упрощает решение задачи слияния объектов.5. Обязательные параметры функций
Задание значений аргументов функций по умолчанию стало отличным расширением возможностей JavaScript. А вот как сделать так, чтобы без передачи некоторых обязательных параметров функции попросту отказывались бы работать:
const isRequired = () => { throw new Error('param is required'); };
const hello = (name = isRequired()) => { console.log(`hello ${name}`) };
// Тут будет выдана ошибка, функции не передан аргумент name
hello();
// Здесь тоже будет ошибка
hello(undefined);
// Эти варианты вызова функции будут работать нормально
hello(null);
hello('David');
Перед нами — дополнительный уровень проверки того, что передаётся функциям.
6. Деструктурирующее присваивание и новые имена извлечённых свойств объектов
Деструктурирование — это новая полезная возможность JavaScript, но иногда свойствам, извлекаемым из объектов, нужно назначать имена, отличающиеся от тех, которые они имеют в этих объектах. Вот как это сделать:
const obj = { x: 1 };
// Теперь мы можем работать с obj.x как с x
const { x } = obj;
// А теперь obj.x для нас выглядит как otherName
const { x: otherName } = obj;
Этот приём полезен в тех случаях, когда нужно избежать конфликта имён переменных или констант.
7. Разбор строк запросов
Многие годы мы, для разбора строк запросов, писали регулярные выражения, но эти времена прошли. Теперь для решения этой задачи можно воспользоваться замечательным API URLSearchParams:
// Предполагается, что мы работаем с "?post=1234&action=edit"
var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?post=1234&action=edit&active=1"
Использовать API
URLSearchParams
куда легче, чем решать те же задачи, применяя регулярные выражения.Итоги
Современный JavaScript очень быстро развивается, в нём постоянно появляются различные полезные улучшения. Но совершенствование языка не означает, что программистам не нужно думать над кодом и искать эффективные решения различных задач, встающих перед ними. Надеемся, те маленькие хитрости JavaScript, о которых мы сегодня говорили, вам пригодятся.
Уважаемые читатели! Знаете какие-нибудь полезные приёмы JS-программирования? Если так — просим ими поделиться.

Комментарии (14)
CoolCmd
30.04.2019 13:30сомневаюсь, что применяют isRequired() на практике. для простой проверки количества параметров проще arguments.length, а для проверки, что в параметре есть что-то осмысленное, нужен как минимум typeof.
VolCh
30.04.2019 14:38Если дошло до isRequired не пора ли посмотреть в сторону статанализа, тайпчекеров и вообще компиляторов статически типизированных языков в JS?
Cerberuser
30.04.2019 14:41С isRequired — приём не для прода, но забавный, стоит запомнить, пожалуй (и да, статическая типизация — не панацея, хотя я сам пишу на TypeScript). Остальное… вот кто из более-менее освоившихся в теме этого не знает, скажите на милость (кроме filter(Boolean), которое с непривычки выглядит как адский хак)?
inoyakaigor
30.04.2019 15:04Оператор… значительно
Не устану нести свет людям: это не оператор в его классическом понимании, а синтаксис.
myArray
.map(item => {
//…
})
// Избавляемся от ненужных значений
.filter(Boolean);
связку map и filter можно заменить, на один reduce:
[…].reduce((prev, curr) => {
const tmp = /*cast to boolean*/
return tmp && prev
}, true)Cerberuser
30.04.2019 17:07+1А последнее, извиняюсь, каким образом? map + filter возвращает массив, reduce в таком исполнении — boolean.
stshk
02.05.2019 20:11-1это магия js ;))))))
[1,2,3].reduce((acc, cur)=>cur%2?acc.concat([cur*3]):acc, [])
Cerberuser
02.05.2019 20:39Нет, про этот-то приём я знаю, я пытался понять, что хотел сказать автор предыдущего комментария своей конструкцией.
stshk
02.05.2019 21:05наверное что-нибудь типа reduce = filter + map:
[0,null,1,2,false,3].reduce((acc, cur)=>Boolean(cur)?acc.concat([cur*3]):acc, [])
может просто написал неправильно
хотя так вот короче и понятнее:
[0,null,1,2,false,3].filter(Boolean).map(i=>i*3)
но 2 прогона =(((
в этом смысле итераторы питона лучше =)
inoyakaigor
03.05.2019 23:56Я просто немного поспешил с ответом. В своей практике я часто привожу массив вида [true, false, true] к переменной в которой хранится показатель того, что все объекты в изначальном массиве содержат нужное свойство или нужное значение у этого свойства
storm_r1der
Можно выделить только
URLSearchParams
, остальное — без комментариев. Очень полезные мелочи — деструктурирующее присваивание и spread-оператор, только не мелочи, и не полезные, а обязательные к использованию. Ну, про обязательные параметры вообще молчу — имхо, я бы гнал "программистов", которые такое практикуют, ссаными тряпкями.Улыбнуло про пустые объекты — в js и так нормального ооп нету (особенности интерпретации — все, сюрприз, превращается в функциональщину и императивщину).
И да, зачем нужны "массивы с уникальными значениями" если уже есть
Set
? Плохой костыль, с учетом того, что дальше мы можем, оперируя памятью (или через консоль, лол, если это незащищенный код на клиенте) запушить туда любые угодные нам значения.Продолжайте переводить подобный кал, не обращая внимания на то, что переводите. Удачи.
JustDont
Всегда приятно смотреть на то, как приходит новый программист на ES6, и первым делом подключает lodash, потому что ему видите ли надо пару объектов слить вместе, а руками он не умеет ^_^
Но вообще деструктурирующее присваивание — это «мелкий» сахар, в том плане, что я бы его обязательным не назвал. С ним красивше, но без него тоже читаемо. А вот spread — это «глубокий» сахар, с его помощью сокращаются целые блоки унылого кода по переприсвоению; и читать код от того, кто его просто не знает — иногда очень мучительно.
storm_r1der
Совершенно с вами согласен. У меня только один вопрос к ru_vds: каким образом подобная чушь, под которой куча гневных комментариев:
1) Набирает 10-15+ рейтинга
2) Практически все отрицательные (по отношению к содержимому статьи) комментарии в диких минусах.
При этом всем, в их недавнем посте про консоли в комментах были ссылки на 3 (3, Карл!) поста с практически ИДЕНТИЧНЫМ содержимым.
*негодует*