可迭代对象
目前所有的内置可迭代对象如下:String
、Array
、TypedArray
、Map
和 Set
,它们的原型对象都实现了 @@``iterator
方法。
可迭代对象必须满足迭代协议
迭代协议
可迭代协议
可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为
要成为可迭代对象, 一个对象必须实现 @@iterator 方法 这意味着对象(或者它原型链上的某个对象)必须有一个键为@@iterator
的属性,可通过常量Symbol.iterator
访问该属性:
迭代器协议
只有实现了一个拥有以下语义(semantic)的 next() 方法,一个对象才能成为迭代器
image.png
自定义迭代器
function makeIterator(array) {
let nextIndex = 0;
return {
next: function () {
return nextIndex < array.length ? {
value: array[nextIndex++],
done: false
} : {
done: true
};
}
};
}
var it = makeIterator(['哟', '呀']);
console.log(it.next().value); // '哟'
console.log(it.next().value); // '呀'
console.log(it.next().done); // true
将对象转换为一个可迭代的对象
const obj = {
a: 1,
b: 2,
c: 3,
log() {
console.log(this.a + this.b)
},
[Symbol.iterator]() { // 可迭代协议
const keys = Object.keys(this)
const len = keys.length
let index = 0;
return {
next: () => { // 迭代器协议
if (index < len) {
return {value: this[keys[index++]], done: false}
} else {
return {done: true}
}
}
}
}
}
for (let iterator of obj) {
console.log(iterator)
}
关闭迭代器
对于for...of的循环,可以由break, throw continue 或return终止。在这些情况下,迭代器关闭。
for-of / for-in
无论是for...in还是for...of语句都是迭代一些东西。它们之间的主要区别在于它们的迭代方式。
for...of
语句遍历可迭代对象定义要迭代的数据。
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
for...in 会迭代原型链上的所有可枚举属性,如需迭代当前对象的可枚举属性,可以使用 obj.hasOwnProperty(key)进行拦截,并且它不记录值,只记录键
【笔记不易,如对您有帮助,请点赞,谢谢】