详解for..of遍历可迭代对象

1. 迭代字面量定义的对象试试

首先看一案例

const obj1 = {
	a: 1,
	b: 2,
	c: 3
};
// const num = ['a', 'b' , 'c']
for(let item of obj1) {
	console.log(item);
}

结果是报错的。

Uncaught TypeError: obj1 is not iterable

这个iterable 是什么。是不是有了就可以遍历了呢,答案是当然了(后边给方案)。

在看一个正面的例子

const num = ['a', 'b' , 'c']			
for (let i of num) {
	console.log(i);
}

// 结果是 a ,b ,c

那就是说数组可以遍历。直接定义字面量对象不可以,问题在哪里呢

都打印一下看下区别

const obj1 = {
	a: 1,
	b: 2,
	c: 3
};
const num = ['a', 'b' , 'c']
console.log(obj1);
console.log(num)

问题就出在这里,谁有这个属性谁就能被for...of和 for ..in 迭代遍历

这些可以被遍历的统统成为可迭代对象

可迭代对象(包括Array, Map, Set, String, TypedArray, arguments对象等等)

语法:

for (variable of iterable) {
    //statements
}

举例:

2.迭代Array

let iterable = [10, 20, 30];

for (let value of iterable) {
    value += 1;
    console.log(value);
}
// 11
// 21
// 31

3. 迭代String

let iterable = "boo";

for (let value of iterable) {
  console.log(value);
}
// "b"
// "o"
// "o"

4. 迭代TypedArray

let iterable = new Uint8Array([0x00, 0xff]);

for (let value of iterable) {
  console.log(value);
}
// 0
// 255

5.迭代Map

let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (let entry of iterable) {
  console.log(entry);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]

for (let [key, value] of iterable) {
  console.log(value);
}
// 1
// 2
// 3

6.迭代Set

let iterable = new Set([1, 1, 2, 2, 3, 3]);

for (let value of iterable) {
  console.log(value);
}
// 1
// 2
// 3

迭代arguments 对象

(function() {
  for (let argument of arguments) {
    console.log(argument);
  }
})(1, 2, 3);

// 1
// 2
// 3

7.迭代 DOM 集合

迭代 DOM 元素集合,比如一个Nodelist对象:下面的例子演示给每一个 article 标签内的 p 标签添加一个 "read" 类。

//注意:这只能在实现了NodeList.prototype[Symbol.iterator]的平台上运行
let articleParagraphs = document.querySelectorAll("article > p");

for (let paragraph of articleParagraphs) {
  paragraph.classList.add("read");
}

8.关闭迭代或者终止

对于for...of的循环,可以由breakthrow  continue    或return终止。在这些情况下,迭代器关闭。
 

const num = ['a', 'b' , 'c']
// console.log(obj1);
// console.log(num)
for (let i of num) {
  if(i === 'b') {
    break
  }
  console.log(i);
}

// 只会打印出来一个 a 就结束了

9. 迭代字面量对象

回到问题开始,我想要用for of 迭代 对象字面量生成的对象。怎么办呢

迭代其他可迭代对象,显式实现可迭代协议的对象。

看例子就会明白(迭代规则必须按照固定的写法。):

const obj1 = {
  a: 1,
  b: 2,
  c: 3
};
obj1[Symbol.iterator] = function() {
  let keys = Object.keys(obj1); //['a','b','c']
  let len = keys.length;
  let n = 0;

  return {
    next: function() {
      if (n < len) {
        return {
          value: {
            k: keys[n],
            v: obj1[keys[n++]]
          },
          done: false
        };
      } else {
        return {
          done: true
        };
      }
    }
  };
};
for (let { k, v } of obj1) {
  // 这里用的是es6中的对象解构赋值
  console.log(k, v);
}
for (let item of obj1) {
  console.log(item);
}

打印结果:

10.迭代最优解

当然这里只是为了理解,es6中有 Object.keys() 、 Object.values()  、 Object.entries() 和for of 配合迭代那是极好的

const obj1 = {
	a: 1,
	b: 2,
	c: 3
};
for(let key of Object.keys(obj1)) {
	console.log(key);
}
// 结果 :  a  b  c
for(let value of Object.values(obj1)) {
	console.log(value);
}
// 结果 :  1 2  3
for(let [index , item] of Object.entries(obj1)) {
    // 这里为啥要用方括号呢。得看你要解构的是什么格式了。
	console.log(index,item);
}
// 结果 a  1  b  2  c  3

 

猜你喜欢

转载自blog.csdn.net/weixin_41229588/article/details/106420405