首先看一案例
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 }
举例:
let iterable = [10, 20, 30];
for (let value of iterable) {
value += 1;
console.log(value);
}
// 11
// 21
// 31
let iterable = "boo";
for (let value of iterable) {
console.log(value);
}
// "b"
// "o"
// "o"
let iterable = new Uint8Array([0x00, 0xff]);
for (let value of iterable) {
console.log(value);
}
// 0
// 255
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
let iterable = new Set([1, 1, 2, 2, 3, 3]);
for (let value of iterable) {
console.log(value);
}
// 1
// 2
// 3
(function() {
for (let argument of arguments) {
console.log(argument);
}
})(1, 2, 3);
// 1
// 2
// 3
迭代 DOM 元素集合,比如一个Nodelist对象:下面的例子演示给每一个 article 标签内的 p 标签添加一个 "read
" 类。
//注意:这只能在实现了NodeList.prototype[Symbol.iterator]的平台上运行
let articleParagraphs = document.querySelectorAll("article > p");
for (let paragraph of articleParagraphs) {
paragraph.classList.add("read");
}
对于for...of
的循环,可以由break
, throw 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 就结束了
回到问题开始,我想要用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);
}
打印结果:
当然这里只是为了理解,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