как согласовать коллекцию JavaScript со своими целями

1656559942 kak soglasovat kollekcziyu javascript so svoimi czelyami

Джо Морган

H5NZkAJJlj3ziw8M5fBVtMUXxuWctECDURYi

Я любил JavaScript, даже когда мир его ненавидел. Но мне всегда было тяжело оправдывать коллекции. Объекты – это нечто вроде хранилища ключ-значения, но на самом деле не так. И они были ужасающими, если нужно было отсортировать или зациклить. Массивы было легче зацикливать, но неловко, если нужно было извлечь конкретное значение без индекса.

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

Было больно.

Сейчас все по-другому. Есть больше видов коллекции. Есть больше способов. Есть лучшие методы и даже однострочные выражения для переключения между типами коллекций. Почему тогда кажется, что мы все еще догадываемся, когда выбираем тип коллекции?

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

Пора покончить с этим. У нас есть не только массивы и объекты. У нас также есть карты, наборы, WeakMaps и WeakSets.

Что же выбрать? Каждая коллекция имеет взлеты и падения. Но в целом на ваш выбор должны повлиять три больших фактора:

  • Итерационный: Можете ли вы перейти в коллекцию напрямую и получить доступ к каждому члену поочередно?
  • Ключ: Можете ли вы найти значение с помощью специального ключа, не беспокоясь о других членах коллекции?
  • Деструктурированный: Можете ли вы быстро и легко разместить фрагменты коллекции в перемене?

Каждый тип коллекции силен в некоторых областях и слаб в других. Есть и другие преимущества и недостатки, но для большинства кодов это большая тройка.

Массивы

Массивы, пожалуй, самая гибкая коллекция. Это делает их отличной точкой для начала изучения коллекций.

Вот список моих учителей начальной школы (имена изменены, чтобы защитить невиновных).

const myTeachers = ['Cooper', 'Simes', 'Butler'];

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

const [firstGrade, secondGrade, ...others] = myTeachers.

Деструктурирование – это быстрый способ извлечь информацию из коллекции в отдельные переменные. Он также может создавать подмножество информации. ПеременнаяfirstGrade имеет значениеCooper . Следующая переменная, secondGrade есть Simes . Последняя сменная немного отличается от трех точек ... мы сохраняем остальные переменные, в этом случае одну, как отдельный массив. Это означает others также является массивом: ['Butler'] . В этом случае, ... есть модель отдыха. В конце концов мы сохраняем остальные ценности.

Вернусь в мою коллекцию учителей. Скажем, вас не волнует порядок, которым меня научили, вас больше интересует алфавитный список. Теперь, прежде чем отсортировать массив, помните, что сортировка является изменяющей функцией, поэтому действие изменит исходный массив. А поскольку порядок имеет значение, вы не желаете вносить постоянные изменения. К счастью, это не большая проблема, поскольку вы можете создать новый массив с помощью оператора распространения: [...myTeachers] .

Причина, по которой можно использовать оператор распространения, заключается в том, что массивы имеют встроенный итератор. что позволяет действовать над коллекцией по одному. Другими словами, массивы есть итерационный. Оператор распространения берет эти элементы и создает новый список по одному. Помещение всего этого в квадратные скобки создает новый массив. Свойство iterable также позволяет делать приятные вещи, например использование цикла for...of или запустите функцию для каждого элемента массива, как это делается из .map и .reduce методы

Вернуться к сортировке. Теперь, когда вы можете создать новый массив, вам не придется беспокоиться о мутациях. Функция сортировки однострочная.

const sortedTeachers = [...myTeachers].sort();

Поскольку массивы можно деструктурировать и итерировать, можно легко извлекать информацию или получать доступ к каждому элементу по одному. Выглядит очень здорово, правда? Конечно, массивы не идеальны. Допустим, вы не знаете порядка массива, но вам нужна моя учительница второго класса. Теперь у вас проблема. Поскольку массивы не имеют ключей, вы не можете получить необходимую информацию. Лучшее, что вы можете сделать, это создать сложный массив пар – массив, содержащий два элемента – вместе с методом массива, чтобы найти нужный.

export const myTeacherPairs = [['first', 'Cooper'], ['second', 'Simes'], ['third', 'Butler']];
return teachers.find(teacherPair => teacherPair[0] === 'second');

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

Проблемы в том, что коллекции нет ключ. Массивы хороши во многих вещах, но хранилища ключей и значений не являются одними. Значит, вы в тупике. Вам нравятся характеристики деструктуризации и итерации. Но получить информацию ключ-значения непросто. Обычно это происходит, когда разработчики обращаются к объектам. Но перед этим вот итог массивов:

✅ Подвергается разрушению

✅ Итерационный

❌ Ключ

Объекты

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

Начните с переписывания моего набора учителей в объект:

const teachers = {  first: "Cooper",  second: "Simes",  third: "Butler",};

Если вам нужно было найти моего учителя второго класса, а другие части объекта не беспокоились, вы можете извлечь его непосредственно: teachers.second . Еще лучше, вы можете перетащить значение непосредственно в переменную с помощью деструктуризации. Это простое предназначение, если переменная соответствует ключу объекта.

const { second } = teachers;

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

function getSecondGradeInfo({ second }) {  const school = "Lakin";  return {    school,    teacher: second  }}

Вещи начинают рушиться, когда вы хотите повторить объект. Вам нужно либо превратить некоторую часть объекта в массив, либо использовать a for...in петля.

Object.keys(teachers).map(grade => `${grade}:${teachers[grade]}`).join(' ');
let myTeacher="";for(const grade in teachers) {  myTeacher += ` ${grade}:${teachers[grade]}`;}

Дела уже становятся немного беспорядочными. Вам нужно либо перебирать ключи, либо изменять переменную. Что хуже, объекты не гарантируют порядок. Вы никогда не можете доверять своим for...in цикл, чтобы получить результаты в нужной последовательности.

Все эти проблемы возникают из-за отсутствия у объекта итерируемого свойства. Object.keys и for...in оба используют итератор, возникающий при превращении ключей в массив.

Кроме того, существуют другие проблемы с объектами. Имеются ограниченные ключевые параметры. Например, цифры нельзя использовать в качестве ключей. Они не так эффективны, как другие коллекции. Но в большинстве своем они хороши для передачи данных без большого количества циклов.

Обобщить:

✅ Подвергается разрушению

❌ Итеративный

✅ Под ключ

карты

Карты – это новый тип коллекции для JavaScript. Они являются подходящим хранилищем «ключ-значение». Это только способ сказать, что они были разработаны специально для этой цели. В отличие от объектов, вам все равно придется явно создать новый экземпляр:

const teachers = new Map();

После этого вы устанавливаете каждый элемент, передавая ключ, а затем значение в качестве аргументов.

teachers.set('first', 'Cooper').set('second', 'Simes').set('third', 'Butler);

Чтобы получить значение, вы вызываете get() способ совместно с заглавием ключа.

teachers.get('second'); // Simes

Это уже может выглядеть немного знакомым. Это мало чем отличается отlocalStorage.setItem(key, value которые, возможно, использовали для хранения данных между посещениями веб-приложения.

Как хранилищ ключ-значения, карты очень великолепны. Они принимают более широкий выбор ключей. И хотя время поиска объектов линейно, время поиска карты будет логарифмическим.

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

let myTeachers="";for([grade, name] of teachers) {  myTeachers += ` ${grade}:${name}`;}

Об этом можно сказать несколько вещей. Может выглядеть так, будто вы деструктурируете карту в начале цикла for. Вы на самом деле не являетесь. Когда вы перебираете карту, вы получаете пару с ключом и значением. Итак, вы фактически деструктурируете массив.

Далее вы можете заметить, что вы все еще изменяете переменную. Это не так здорово. К счастью, поскольку карта является итерационной, вы можете использовать оператор распространения, чтобы превратить карту в массив пар. Это означает

[...teachers]

состоянии

[  ['first', 'Cooper'],  ['second', 'Simes'],  ['third', 'Butler'],]

После преобразования карты в массив можно отобразить элементы, чтобы создать свою строку.

[...teachers].map(([grade, name]) => `${grade}:${name}`).join();

Это означает, что у вас есть доступ ко всем методам массива в трех коротких символах.

О и поскольку он итерируется, порядок сохраняется. Если вы добавите учителя первого класса в начале, вы получите его в начале.

Итак, каковы недостатки? Больше всего – отсутствие прямой деструктуризации. Вы не можете получить значение без вызова get()метода или путём превращения в массив. Это означает, что передача данных между функциями становится более сложной. Вы также не можете представлять карты в виде строки JSON. Поэтому в ближайшее время вы не будете извлекать карты из API.

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

Обобщить:

❌ Подвергается разрушению

✅ Итерационный

✅ Под ключ

Перемещение между

Вы наверняка заметили одну неприятную закономерность. Нет никакой коллекции, которая может сделать все.

К счастью, это не столь большая проблема, как вы думаете.

Вы уже видели, что можно превратить карту в массив с помощью оператора распространения. Вы также можете пойти по другому пути и превратить массив в карту, передав его в конструктор.

Вы также можете ускорить начальный процесс создания, передавая массив пар:

const myTeachers = [  ['first', 'Cooper'],  ['second', 'Simes'],  ['third', 'Butler'],]const teachers = new Map(myTeachers);

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

Объекты становятся лучше. С Object.entries() вы можете создать массив пар из объекта.

const teachers = {  first: "Cooper",  second: "Simes",  third: "Butler",};
const myTeachers = Object.entries(teachers);
myTeachers[0]// ['first', 'Cooper']

Это означает, что когда у вас есть объект, у вас есть доступ к методам массива с простым преобразованием. Но вернуться назад немного тяжелее. Теперь есть предложение для Object.fromEntries() который возьмет массив пар и создаст объект. Но до этого еще немного.

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

Другими словами, вы можете просмотреть имеющиеся у вас данные и нужный код и выбрать подходящий тип сбора. Если другой функции требуется другой тип, напишите простое преобразование. Больше не нужно гадать. Больше никаких разочарований. Вы можете сравнить свою коллекцию со своими целями, а не код с коллекцией.

Добавить комментарий

Ваш адрес email не будет опубликован.