배열과 객체는 다양한 프로그래밍 언어에서 중요한 역할을 합니다. 이 기사에서는 JavaScript에서 일반적으로 사용되는 배열 순회 및 객체 순회 방법과 각 방법의 차이점 및 사용 시 주의 사항을 소개합니다.
JS의 지속적인 개발로 인해 ES7 사양을 기준으로 10가지 이상의 순회 방법이 있습니다. 다음은 배열의 일반적인 순회 방법을 소개하기 위해 유사한 기능을 가진 메서드 그룹입니다.
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 });
요약
some,every
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
Summary
filter, map
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 }, // ]
Summary
find 및 findIndex
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 // '底部导航';
Summary
reduce, ReduceRight
reduce 메서드는 두 개의 매개변수를 받습니다. 첫 번째 매개변수는 콜백 함수(콜백)이고 두 번째 매개변수는 초기값(initialValue)입니다. reduceRight 메소드는 Reduce 실행의 반대 방향(오른쪽에서 왼쪽으로)이라는 점을 제외하면 완전히 일치합니다. 콜백 함수는 4개의 매개변수를 받습니다:객체 배열의 특정 속성의 합을 계산
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 }
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
일반적으로 사용되는 순회 종료 및 성능표 비교
是否可终止 | ||||
---|---|---|---|---|
** | 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: '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)
后者将会创建一个全局变量。
for in 的循环顺序,参考【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']
小结
用于获取对象自身所有的可枚举的属性值,但不包括原型中的属性,然后返回一个由属性名组成的数组。
我们对比了多种常用遍历的方法的差异,在了解了这些之后,我们在使用的时候需要好好思考一下,就能知道那个方法是最合适的。欢迎大家纠正补充。
更多编程相关知识,请访问:编程视频!!
위 내용은 JavaScript에서 배열과 객체를 순회하는 몇 가지 일반적인 방법에 대한 간략한 토론의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!