JS, обычно используемый обход цикла, вы знаете несколько

внешний интерфейс JavaScript
JS, обычно используемый обход цикла, вы знаете несколько

Это 100-я оригинальная статья без воды. Если вы хотите получить больше оригинальных статей, выполните поиск в общедоступном аккаунте и подпишитесь на нас~ Эта статья была впервые опубликована в блоге Zhengcaiyun:JS, обычно используемый обход цикла, вы знаете несколько

佳民.png

предисловие

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

обход массива

С непрерывным развитием JS существует более десяти методов обхода по спецификации ES7. Ниже приведена группа методов с похожими функциями для представления общих методов обхода массивов.

для, для каждого,for ...of

const list = [1, 2, 3, 4, 5, 6, 7, 8,, 10, 11];

for (let i = 0, len = list.length; i < len; i++) {
  if (list[i] === 5) {
    break; // 1 2 3 4
    // continue; // 1 2 3 4 6 7 8 undefined 10 11
  }
  console.log(list[i]);
}

for (const item of list) {
  if (item === 5) {
    break; // 1 2 3 4
    // continue; // 1 2 3 4 6 7 8 undefined 10 11
  }
  console.log(item);
}

list.forEach((item, index, arr) => {
  if (item === 5) return;
  console.log(index); // 0 1 2 3 5 6 7 9 10
  console.log(item); // 1 2 3 4 6 7 8  10 11
});

резюме

  • Все три в основном обходят массив слева направо.
  • forEach не может выйти из цикла, for и for ..of можно пропустить или прервать с помощью break или continue.
  • for ...of напрямую обращается к фактическому элементу. для обхода индекса массива функция обратного вызова forEach имеет больше параметров, и можно получить элемент, индекс и исходный массив.
  • for ...of и for также выполняются, если в массиве есть пустые элементы.

некоторые, каждый

const list = [
  { name: '头部导航', backward: false },
  { name: '轮播', backward: true },
  { name: '页脚', backward: false },
];
const someBackward = list.some(item => item.backward);
// someBackward: true
const everyNewest = list.every(item => !item.backward);
// everyNewest: false

резюме

  • Оба используются для условного суждения массива, и оба возвращают логическое значение.
  • Оба могут быть прерваны
  • some Если элемент удовлетворяет условию, возвращает true, и цикл прерывается, если все элементы не удовлетворяют условию, возвращает false.
  • каждый В отличие от некоторых, если полезный элемент не удовлетворяет условию, он возвращает false, и цикл прерывается; если все элементы удовлетворяют условию, он возвращает true.

фильтр, карта

const list = [
{ name: '头部导航', type: 'nav', id: 1 },,
{ name: '轮播', type: 'content', id: 2 },
{ name: '页脚', type: 'nav', id: 3 },
];
const resultList = list.filter(item => {
  console.log(item);
  return item.type === 'nav';
});
// resultList: [
//   { name: '头部导航', type: 'nav', id: 1 },
//   { name: '页脚', type: 'nav', id: 3 },
// ]

const newList = list.map(item => {
  console.log(item);
  return item.id;
});
// newList: [1, empty, 2, 3]

// list: [
//   { name: '头部导航', type: 'nav', id: 1 },
//   empty,
//   { name: '轮播', type: 'content', id: 2 },
//   { name: '页脚', type: 'nav', id: 3 },
// ]

резюме

  • Оба генерируют новый массив, и ни один из них не изменит исходный массив (за исключением обхода массива объектов, работы с объектом-элементом в функции обратного вызова)
  • Оба будут пропускать пустые элементы. Заинтересованные студенты могут распечатать его самостоятельно.
  • map сформирует новый массив с возвращаемым значением функции обратного вызова, а длина массива будет такой же, как у исходного массива.
  • filter сформирует новый массив элементов, отвечающих условиям функции обратного вызова, и длина массива отличается от исходного массива.
  • Новые элементы массива, сгенерированные картой, можно настраивать.
  • Новые элементы массива, сгенерированные фильтром, не могут быть настроены и согласуются с соответствующими исходными элементами массива.

найти, найтииндекс

const list = [
{ name: '头部导航', id: 1 },
{ name: '轮播', id: 2 },
{ name: '页脚', id: 3 },
];
const result = list.find((item) => item.id === 3);
// result: { name: '页脚', id: 3 }
result.name = '底部导航';
// list: [
//   { name: '头部导航', id: 1 },
//   { name: '轮播', id: 2 },
//   { name: '底部导航', id: 3 },
// ]

const index = list.findIndex((item) => item.id === 3);
// index: 2
list[index].name // '底部导航';

резюме

  • Оба используются для поиска элементов массива.
  • Метод find возвращает значение первого элемента массива, удовлетворяющего функции обратного вызова. Возвращает неопределенное значение, если оно не существует.
  • findIndex Возвращает индекс элемента, найденного в массиве, а не его значение, или -1, если он не существует.

уменьшить, уменьшитьПравильно

Метод reduce принимает два параметра, первый параметр — это функция обратного вызова (callback), а второй параметр — начальное значение (initialValue).

Метод reduceRight точно такой же, за исключением того, что направление выполнения сокращения противоположно (справа налево).

Функция обратного вызова получает четыре параметра:

  • аккумулятор: MDN интерпретируется как аккумулятор, но я не думаю, что это целесообразно.По моему мнению, он должен быть до текущего элемента, а все предыдущие элементы массива обрабатываются функцией обратного вызова.Накопленный результат.
  • current: текущий выполняемый элемент массива.
  • currentIndex: индекс элемента массива, выполняемого в данный момент.
  • sourceArray: исходный массив, то есть массив, вызывающий метод сокращения.

Если начальное значение не передано, метод сокращения выполнит функцию обратного вызова, начиная с индекса 1. Если начальное значение передано, оно начнется с индекса 0 и выполнит обратный вызов накопительно на основе начального значения.

Вычисляет сумму свойства массива объектов
const list  = [
  { name: 'left', width: 20 },
  { name: 'center', width: 70 },
  { name: 'right', width: 10 },
];
const total = list.reduce((currentTotal, item) => {
  return currentTotal + item.width;
}, 0);
// total: 100
Дедупликация массива объектов и подсчет количества повторений каждого элемента
const list  = [
  { name: 'left', width: 20 },
  { name: 'right', width: 10 },
  { name: 'center', width: 70 },
  { name: 'right', width: 10 },
  { name: 'left', width: 20 },
  { name: 'right', width: 10 },
];
const repeatTime = {};
const result = list.reduce((array, item) => {
  if (repeatTime[item.name]) {
    repeatTime[item.name]++;
    return array;
  }
  repeatTime[item.name] = 1;
  return [...array, item];
}, []);
// repeatTime: { left: 2, right: 3, center: 1 }
// result: [
//   { name: 'left', width: 20 },
//   { name: 'right', width: 10 },
//   { name: 'center', width: 70 },
// ]
Получение максимального/минимального значения массива объектов
const list  = [
  { name: 'left', width: 20 },
  { name: 'right', width: 30 },
  { name: 'center', width: 70 },
  { name: 'top', width: 40 },
  { name: 'bottom', width: 20 },
];
const max = list.reduce((curItem, item) => {
  return curItem.width >= item.width ? curItem : item;
});
const min = list.reduce((curItem, item) => {
  return curItem.width <= item.width ? curItem : item;
});
// max: { name: "center", width: 70 }
// min: { name: "left", width: 20 }

сокращение очень мощное, проверьте это, чтобы узнать больше трюков и трюков«25 расширенных способов использования Array Reduce, которые вы должны знать»

Сравнение производительности

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

var list = Array(100000).fill(1)

console.time('for');
for (let index = 0, len = list.length; index < len; index++) {
}
console.timeEnd('for');
// for: 2.427642822265625 ms

console.time('every');
list.every(() => { return true })
console.timeEnd('every')
// some: 2.751708984375 ms

console.time('some');
list.some(() => { return false })
console.timeEnd('some')
// some: 2.786590576171875 ms

console.time('foreach');
list.forEach(() => {})
console.timeEnd('foreach');
// foreach: 3.126708984375 ms

console.time('map');
list.map(() => {})
console.timeEnd('map');
// map: 3.743743896484375 ms

console.time('forof');
for (let index of list) {
}
console.timeEnd('forof')
// forof: 6.33380126953125 ms

Как видно из распечатанных результатов, цикл for является самым быстрым, а цикл for of — самым медленным.

Прекращение общего обхода, сравнение таблицы производительности

Может ли он быть прекращен
**** break continue return Производительность (мс)
for Прекратить ✅ Выпрыгнуть из этого круга ✅ 2.42
forEach 3.12
map 3.74
for of Прекратить ✅ Выпрыгнуть из этого круга ✅ 6.33
some вернуть истину ✅ 2.78
every вернуть ложь ✅ 2.75

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

обход объекта

При обходе объекта часто необходимо пройти по ключам и значениям объектов.ES5 предусматривает...in для обхода объектов.Однако он задействует "перечислимые свойства" и свойства цепочки прототипов свойств объекта.Суть исследует различные способы обхода объектов, а также выделяют некоторые характеристики общих способов.

for in

Object.prototype.fun = () => {};const obj = { 2: 'a', 1: 'b' };for (const i in obj) {  console.log(i, ':', obj[i]);}// 1: b// 2: a// fun : () => {} Object 原型链上扩展的方法也被遍历出来for (const i in obj) {  if (Object.prototype.hasOwnProperty.call(obj, i)) {      console.log(i, ':', obj[i]);    }}// name : a 不属于自身的属性将被 hasOwnProperty 过滤

резюме

При использовании цикла for in возвращаются все перечисляемые свойства, к которым можно получить доступ через объект, включая свойства, существующие в экземпляре, и экземпляры, существующие в прототипе. Если вам нужно получить только свойства экземпляра объекта, вы можете использовать hasOwnProperty для фильтрации.

При использовании использовать(const x in a)вместо(x in a)Последний создаст глобальную переменную.

Информацию о последовательности циклов см. в [Полное руководство по JavaScript] (седьмое издание) 6.6.1.

  • Сначала перечислите строковые свойства, имена которых являются целыми неотрицательными числами, в порядке от наименьшего к наибольшему. Это правило означает, что свойства массивов и массивоподобных объектов перечисляются по порядку.
  • После перечисления всех свойств с индексами, подобными массивам, после перечисления всех оставшихся свойств со строковыми именами (включая имена, которые выглядят как целые отрицательные числа или числа с плавающей запятой). Свойства перечислены в том порядке, в котором они были добавлены к объекту. Для свойств, определенных в литерале объекта, они перечислены в том порядке, в котором они появляются в литерале.
  • Наконец, свойства, названные объектами символов, перечислены в том порядке, в котором они были добавлены к объекту.

Object.keys

Object.prototype.fun = () => {};const str = 'ab';console.log(Object.keys(str));// ['0', '1']const arr = ['a', 'b'];console.log(Object.keys(arr));// ['0', '1']const obj = { 1: 'b', 0: 'a' };console.log(Object.keys(obj));// ['0', '1']

резюме

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

Object.values

Object.prototype.fun = () => {};const str = 'ab';console.log(Object.values(str));// ['a', 'b']const arr = ['a', 'b'];console.log(Object.values(arr));// ['a', 'b']const obj = { 1: 'b', 0: 'a' };console.log(Object.values(obj));// ['a', 'b']

резюме

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

Object.entries

const str = 'ab';for (const [key, value] of Object.entries(str)) {    console.log(`${key}: ${value}`);}// 0: a// 1: bconst arr = ['a', 'b'];for (const [key, value] of Object.entries(arr)) {    console.log(`${key}: ${value}`);}// 0: a// 1: bconst obj = { 1: 'b', 0: 'a' };for (const [key, value] of Object.entries(obj)) {    console.log(`${key}: ${value}`);}// 0: a// 1: b

резюме

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

Object.getOwnPropertyNames

Object.prototype.fun = () => {};Array.prototype.fun = () => {};const str = 'ab';console.log(Object.getOwnPropertyNames(str));// ['0', '1', 'length']const arr = ['a', 'b'];console.log(Object.getOwnPropertyNames(arr));// ['0', '1', 'length']const obj = { 1: 'b', 0: 'a' };console.log(Object.getOwnPropertyNames(obj));// ['0', '1']

резюме

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

Суммировать

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

Рекомендуемое чтение

Поговорим о Дено.

Схема кэширования списка страниц H5

работы с открытым исходным кодом

  • Zhengcaiyun интерфейсный таблоид

адрес с открытым исходным кодомwww.zoo.team/openweekly/(На главной странице официального сайта таблоида есть группа обмена WeChat)

Карьера

ZooTeam, молодая, увлеченная и творческая команда, связанная с отделом исследований и разработок продукции Zhengcaiyun, базируется в живописном Ханчжоу. В настоящее время в команде более 40 фронтенд-партнеров, средний возраст которых составляет 27 лет, и почти 30% из них — инженеры полного стека, настоящая молодежная штурмовая группа. В состав членов входят «ветераны» солдат из Ali и NetEase, а также первокурсники из Чжэцзянского университета, Университета науки и технологий Китая, Университета Хандянь и других школ. В дополнение к ежедневным деловым связям, команда также проводит технические исследования и фактические боевые действия в области системы материалов, инженерной платформы, строительной платформы, производительности, облачных приложений, анализа и визуализации данных, а также продвигает и внедряет ряд внутренних технологий. Откройте для себя новые горизонты передовых технологических систем.

Если вы хотите измениться, вас забросали вещами, и вы надеетесь начать их бросать; если вы хотите измениться, вам сказали, что вам нужно больше идей, но вы не можете сломать игру; если вы хотите изменить , у вас есть возможность добиться этого результата, но вы не нужны; если вы хотите изменить то, чего хотите достичь, вам нужна команда для поддержки, но вам некуда вести людей; если вы хотите изменить установившийся ритм, это будет "5 лет рабочего времени и 3 года опыта работы"; если вы хотите изменить исходный Понимание хорошее, но всегда есть размытие того слоя оконной бумаги.. , Если вы верите в силу веры, верьте, что обычные люди могут достичь необыкновенных вещей, и верьте, что они могут встретить лучшего себя. Если вы хотите участвовать в процессе становления бизнеса и лично способствовать росту фронтенд-команды с глубоким пониманием бизнеса, надежной технической системой, технологиями, создающими ценность, и побочным влиянием, я думаю, что мы должны говорить. В любое время, ожидая, пока вы что-нибудь напишете, отправьте это наZooTeam@cai-inc.com