js使用循环遍历语句有很多种,比如 for , forEach , for...in for...of 等等

for

普通的循环遍历,根据指定的长度遍历,不能遍历对象

for (let i = 0; i < 10; i++) {
    console.log(i);
}

forEach

forEach是用来遍历数组的,只能遍历数组,不能遍历NodeLists

let arr = [1,2,3,4];
arr.forEach((item, idx, arr) => {
    console.log(item);
})

// forEach执行async函数
[1,2,3].forEach(async (item) => {
  let a = await item;
})

for和forEach区别

  • for循环要提前知道要遍历的次数,而forEach不需要
  • for可以灵活控制循环的次数,forEach只能遍历整个数组
  • for可以中途退出,forEach不行

for...in

for...in语句是以任何顺序遍历一个对象的可枚举属性,for...in会遍历原型中的属性和方法,一般配合hasOwnProperty来避免这个问题

function Person () {
  this.name = "kelen";
}

var obj = { age: 19 }
obj.__proto__ = new Person();

for (k in obj) {
  // 打印出原型中的属性和方法
  console.log(k);	// age name
}

for (k in obj) {
  if (obj.hasOwnProperty(k))
    console.log(k);	// age
}

for...of

for...of语句创建一个循环来迭代可迭代的对象,可以遍历的对象有StringArrayTypedArrayMapSet如果遍历一个Object,会报错o is not iterable

let animals = ['🐔', '🐷', '🐑', '🐇'];
let names = ['Gertrude', 'Henry', 'Melvin', 'Billy Bob'];

for (let animal of animals) {
  let nameIdx = Math.floor(Math.random() * names.length);

  console.log(`${names[nameIdx]} the ${animal}`);
}

for...of还可以遍历字符串

let str = 'abcde';

for (let char of str) {
  console.log(char.toUpperCase().repeat(3));
}

【扩展】迭代器

es6里的迭代器并不是一种新的语法或者是新的内置对象(构造函数),而是一种协议,所有遵循了这个协议的对象都可以称之为迭代器对象,所以说迭代器是一种协议,一个统一的接口标准,两个属性都不返回值也不会报错,但是不符合协议标准,就不能称作迭代器了

内置可迭代对象

都是内置可迭代对象(Object不是),因为原型对象都有一个@@iterator方法,例如

var arr = [1,2,3];
var arrIteratorFn = arr[Symbol.iterator]; // arr迭代函数
var str = '1234';    
var strIteratorFn = str[Symbol.iterator]; // str迭代函数

自定义一个可迭代对象

let myInterable = {};
myInterable[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
}
let arr = [...myInterable]; // 展开语法...也实现了迭代协议,结果返回[1,2,3]

for...of语句可以遍历上面的myInterable,其他遍历方法是没法实现的

for (let item of myInterable) {
  console.log(item);
}

遍历NodeLists

const elements = document.querySelectorAll('.foo');
for (const element of elements) {
    element.addEventListener('click', doSomething);
}

for...of和for...in的区别

  1. for...of获取到的是值,for...in获取到的是数组的下标或者对象的key
  2. for...of可以遍历 MapSetgeneratorDOM node collectionarguments对象,for...in不行