Heim  >  Artikel  >  Web-Frontend  >  Eine kurze Diskussion über mehrere gängige Methoden zum Durchlaufen von Arrays und Objekten in JavaScript

Eine kurze Diskussion über mehrere gängige Methoden zum Durchlaufen von Arrays und Objekten in JavaScript

青灯夜游
青灯夜游nach vorne
2021-06-25 11:21:422701Durchsuche

Arrays und Objekte spielen in verschiedenen Programmiersprachen eine wichtige Rolle. In diesem Artikel werden die häufig verwendeten Array-Traversal- und Objekt-Traversal-Methoden in JavaScript, die Unterschiede zwischen den einzelnen Methoden und Vorsichtsmaßnahmen bei deren Verwendung vorgestellt.

Eine kurze Diskussion über mehrere gängige Methoden zum Durchlaufen von Arrays und Objekten in JavaScript

Array-Traversal

Mit der kontinuierlichen Weiterentwicklung von JS gibt es ab der ES7-Spezifikation mehr als zehn Traversal-Methoden. Im Folgenden finden Sie eine Gruppe von Methoden mit ähnlichen Funktionen, um die gängigen Durchlaufmethoden für Arrays vorzustellen.

for, forEach, 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
});

Zusammenfassung

  • Alle drei sind grundlegende Durchläufe des Arrays von links nach rechts
  • forEach kann nicht aus der Schleife ausbrechen; for und for . .of kann Pause oder Fortsetzung verwenden, um zu überspringen oder zu unterbrechen.
  • for ...of greift direkt auf das eigentliche Element zu. for durchläuft den Array-Index, und die Rückruffunktion forEach verfügt über umfangreichere Parameter, und alle Elemente, Indizes und ursprünglichen Arrays können abgerufen werden.
  • for ...of und for werden auch ausgeführt, wenn leere Elemente im Array vorhanden sind.

some, every

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

Zusammenfassung

  • Beide werden zur Beurteilung von Array-Bedingungen verwendet und beide geben einen booleschen Wert zurück , true wird zurückgegeben und die Schleife wird unterbrochen; wenn nicht alle Elemente die Bedingung erfüllen, wird false zurückgegeben.
  • every ist das Gegenteil von some. Wenn das nützliche Element die Bedingung nicht erfüllt, wird „false“ zurückgegeben, und die Schleife wird unterbrochen, wenn alle Elemente die Bedingung erfüllen.
  • Filter, Karte

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

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

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

Beide generieren ein neues Array und ändern das ursprüngliche Array nicht (mit Ausnahme des Durchlaufens des Objektarrays und der Bedienung des Elementobjekts in der Rückruffunktion)

Beide überspringen leere Elemente. Interessierte Schüler können es selbst ausdrucken.
  • map erstellt ein neues Array mit dem Rückgabewert der Rückruffunktion, und die Länge des Arrays entspricht der des ursprünglichen Arrays.
  • filter erstellt ein neues Array mit Elementen, die die Bedingungen der Rückruffunktion erfüllen. Die Länge des Arrays unterscheidet sich vom ursprünglichen Array.
  • Die von der Karte generierten neuen Array-Elemente sind anpassbar. Die von
  • filter generierten neuen Array-Elemente können nicht angepasst werden und stimmen mit den entsprechenden ursprünglichen Array-Elementen überein.
  • find und findIndex

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

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

Beide werden zum Suchen von Array-Elementen verwendet.

Die Suchmethode gibt den Wert des ersten Elements im Array zurück, das die Rückruffunktion erfüllt. Gibt undefiniert zurück, wenn es nicht existiert.
  • findIndex Es gibt den Index des im Array gefundenen Elements anstelle seines Werts zurück und gibt -1 zurück, wenn es nicht vorhanden ist. Die Methode
  • reduce, ReduceRight

reduce empfängt zwei Parameter, der erste Parameter ist die Rückruffunktion (Callback) und der zweite Parameter ist der Anfangswert (initialValue). Die Methode „reduceRight“ stimmt vollständig mit ihr überein, mit der Ausnahme, dass sie in die entgegengesetzte Richtung der Ausführung von „reduce“ erfolgt (von rechts nach links).

Die Rückruffunktion erhält vier Parameter:

Akkumulator: MDN erklärt es als Akkumulator, aber ich halte es für unangemessen, es sollte das akkumulierte Ergebnis aller vorherigen Array-Elemente sein, die von der Rückruffunktion verarbeitet wurden des aktuellen Elements.

aktuell: Das Array-Element, das gerade ausgeführt wird.
  • currentIndex: Der Index des Array-Elements, das gerade ausgeführt wird.
  • sourceArray: Das ursprüngliche Array, das das Array ist, in dem die Reduzierungsmethode aufgerufen wird.
  • Wenn kein Anfangswert übergeben wird, führt die Reduce-Methode die Callback-Funktion ab Index 1 aus. Wenn ein Anfangswert übergeben wird, wird die Callback-Funktion kumulativ ab Index 0 und basierend auf dem Anfangswert ausgeführt.
Berechnen Sie die Summe eines bestimmten Attributs des Objektarrays
const list  = [
  { name: &#39;left&#39;, width: 20 },
  { name: &#39;center&#39;, width: 70 },
  { name: &#39;right&#39;, width: 10 },
];
const total = list.reduce((currentTotal, item) => {
  return currentTotal + item.width;
}, 0);
// total: 100

Deduplizierung des Objektarrays und zählen Sie die Anzahl der Wiederholungen jedes Elements

const list  = [
  { name: &#39;left&#39;, width: 20 },
  { name: &#39;right&#39;, width: 10 },
  { name: &#39;center&#39;, width: 70 },
  { name: &#39;right&#39;, width: 10 },
  { name: &#39;left&#39;, width: 20 },
  { name: &#39;right&#39;, 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: &#39;left&#39;, width: 20 },
//   { name: &#39;right&#39;, width: 10 },
//   { name: &#39;center&#39;, width: 70 },
// ]

Ermitteln Sie den Maximal-/Minimalwert des Objektarrays

const list  = [
  { name: &#39;left&#39;, width: 20 },
  { name: &#39;right&#39;, width: 30 },
  { name: &#39;center&#39;, width: 70 },
  { name: &#39;top&#39;, width: 40 },
  { name: &#39;bottom&#39;, 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 }

reduce ist sehr leistungsstark und noch mehr. Duoqi Jiyinqiao empfiehlt, sich diesen Artikel „25 erweiterte Array-Reduzierung, die Sie kennen müssen“ anzusehen Traversierungsmethoden? Versuchen wir es im Chrome-Browser. Ich führe jede Schleife zehnmal aus, entferne die Maximal- und Minimalwerte und errechne den Durchschnitt, um den Fehler zu reduzieren.

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

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

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

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

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

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

console.time(&#39;forof&#39;);
for (let index of list) {
}
console.timeEnd(&#39;forof&#39;)
// forof: 6.33380126953125 ms
Aus den Druckergebnissen geht hervor, dass die for-Schleife am schnellsten und die for-of-Schleife am langsamsten ist

Häufig verwendete Traversal-Beendigung und Leistungstabellenvergleich

是否可终止


** break continue return 性能(ms)
for 终止 ✅ 跳出本次循环 ✅ 2.42
forEach 3.12
map 3.74
for of 终止 ✅ 跳出本次循环 ✅ 6.33
some return true  ✅ 2.78
every return false ✅ 2.75

最后,不同浏览器内核 也会有些差异,有兴趣的同学也可以尝试一下。

对象遍历

在对象遍历中,经常需要遍历对象的键、值,ES5 提供了 for...in 用来遍历对象,然而其涉及对象属性的“可枚举属性”、原型链属性等,下面将从 Object 对象本质探寻各种遍历对象的方法,并区分常用方法的一些特点。

for in

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

小结

使用 for in 循环时,返回的是所有能够通过对象访问的、可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例。如果只需要获取对象的实例属性,可以使用 hasOwnProperty 进行过滤。

使用时,要使用(const x in a)而不是(x in a)后者将会创建一个全局变量。

for in 的循环顺序,参考【JavaScript 权威指南】(第七版)6.6.1。

  • 先列出名字为非负整数的字符串属性,按照数值顺序从最小到最大。这条规则意味着数组和类数组对象的属性会按照顺序被枚举。
  • 在列出类数组索引的所有属性之后,在列出所有剩下的字符串名字(包括看起来像整负数或浮点数的名字)的属性。这些属性按照它们添加到对象的先后顺序列出。对于在对象字面量中定义的属性,按照他们在字面量中出现的顺序列出。
  • 最后,名字为符号对象的属性按照它们添加到对象的先后顺序列出。

Object.keys

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

小结

用于获取对象自身所有的可枚举的属性值,但不包括原型中的属性,然后返回一个由属性名组成的数组。

Object.values

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

小结

用于获取对象自身所有的可枚举的属性值,但不包括原型中的属性,然后返回一个由属性值组成的数组。

Object.entries

const str = &#39;ab&#39;;for (const [key, value] of Object.entries(str)) {    console.log(`${key}: ${value}`);}// 0: a// 1: bconst arr = [&#39;a&#39;, &#39;b&#39;];for (const [key, value] of Object.entries(arr)) {    console.log(`${key}: ${value}`);}// 0: a// 1: bconst obj = { 1: &#39;b&#39;, 0: &#39;a&#39; };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 = &#39;ab&#39;;console.log(Object.getOwnPropertyNames(str));// [&#39;0&#39;, &#39;1&#39;, &#39;length&#39;]const arr = [&#39;a&#39;, &#39;b&#39;];console.log(Object.getOwnPropertyNames(arr));// [&#39;0&#39;, &#39;1&#39;, &#39;length&#39;]const obj = { 1: &#39;b&#39;, 0: &#39;a&#39; };console.log(Object.getOwnPropertyNames(obj));// [&#39;0&#39;, &#39;1&#39;]

小结

用于获取对象自身所有的可枚举的属性值,但不包括原型中的属性,然后返回一个由属性名组成的数组。

总结

我们对比了多种常用遍历的方法的差异,在了解了这些之后,我们在使用的时候需要好好思考一下,就能知道那个方法是最合适的。欢迎大家纠正补充。

更多编程相关知识,请访问:编程视频!!

Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über mehrere gängige Methoden zum Durchlaufen von Arrays und Objekten in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen