JavaScript迭代协议
文章目录
开场 | Question
一道面试题:for-in
和for-of
的区别?
let babies = ['hpy', 'zs', 'yxz', 'hfcj', 'zpj', 'cfy', 'yxx', 'lyc', 'zls', 'yxn', 'cym'];
babies[Symbol.iterator] = function* (){
let index = 0;
while(index < this.length) {
index++;
yield this[0];
}
}
for(let baby of babies) {
console.log(baby); // ?
}
迭代协议 | Iteration Protocol
ES6新增了
Set
、Map
类型,他们和Array
、Object
类型很像,Array
、Object
都是可以遍历的,但是Set
、Map
都不能用for
循环遍历,解决这个问题有两种方案,一种是为Set、Map单独新增一个用来遍历的API,另一种是为Set、Map、Array、Object新增一个统一的遍历API。ES6选择使用一种设计标准,来统一所有可遍历类型的遍历方式。
Iterator
正是这样一种标准。
迭代协议具体分为两个协议:可迭代协议(Iterable Protocols)和迭代器协议(Iterator Protocols)。
可迭代协议 | Iterable
可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为
要成为可迭代对象, 一个对象必须实现
@@iterator
方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为@@iterator
的属性,可通过常量Symbol.iterator
访问该属性。
Symbol.iterator
是一个无参数的函数,其返回值为一个迭代器。
let arr = ['a', 'b'];
let it = arr[Symbol.iterator](