JS常用的循环遍历

数组遍历

for 、forEach、for…of

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 9 10
});

小结

  • 这三种循环都是从左到右遍历数组;
  • forEach 无法跳出循环;forfor…of 可以使用 break 或者 countinue 跳出循环或中断循环;
  • for…of 直接访问的是实际元素。for 遍历数组索引,forEach 回调函数参数更丰富,元素、索引、原数组都可以获取;
  • for…offor 如果数组中存在空元素,同样会执行;

some、every

COPY
1
2
3
4
5
6
7
8
9
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;
  • every 若有一元素不满足条件,返回 false,循环中断;所有元素满足条件,返回 true;

filter、map

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 会将符合回调函数条件的元素组成一个新数组,数组长度与原数组不同;
  • map 生成的新数组元素是可自定义;
  • filter 生成的新数组元素不可自定义,与对应原数组元素一致;

find、findIndex

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const list = [
{ name: "头部导航", id: 1 },
{ name: "轮播", id: 2 },
{ name: "页脚", id: 3 },
{ 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 },
// { name: '页脚', id: 3 },
// ]

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

小结

  • 二者都是用来查找数组元素;
  • find 方法返回数组中满足 callback 函数的第一个元素的值。如果不存在返回 undefined;
  • findIndex 它返回数组中找到的元素的索引,而不是其值,如果不存在返回 -1;

对象遍历

for in

COPY
1
2
3
4
5
6
7
8
9
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) ,后者将会创建一个全局变量;

Object.keys

  • 用于获取对象自身所有的可枚举的属性值,但不包括原型中的属性,然后返回一个由属性名组成的数组;
  • 该对象可以是 数组Array、对象Object、字符串String;
  • 当该对象为 字符串String 时,在 ES5 里,它会抛出 TypeError。在 ES2015 中,非对象的参数将被强制转换为一个对象;

Object.values

COPY
1
2
3
var an_obj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.values(an_obj));
// ['b', 'c', 'a']
  • 用于获取对象自身所有的可枚举的属性值,但不包括原型中的属性,然后返回一个由属性值组成的数组;
  • 当 obj 的可以值为数字时,返回顺序按照数字大小从小到大返回
  • 同上

Object.entrise

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const obj = { foo: "bar", baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

// array like object
const obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

// array like object with random key ordering
const anObj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

// non-object argument will be coerced to an object
console.log(Object.entries("foo")); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]

// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}

Object.getOwnPropertyNames

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

COPY
1
2
3
4
Object.prototype.fun = () => {};
var obj = { a: 1, b: 2 };
console.log(Object.getOwnPropertyNames(obj));
// ["a", "b"]

面试考点

  1. for 、for in 、for…of 、 forEach 的区别
  2. Object.keys 、 Object.values
作者: 果汁
文章链接: https://guozhigq.github.io/post/5ef4056b.html
版权声明: All posts on this blog are licensed under the CC BY-NC-SA 4.0 license unless otherwise stated. Please cite 果汁来一杯 !