迭代协议
迭代协议具体分为两个协议:可迭代协议和迭代器协议
可迭代对象
实现了可迭代协议的对象。
迭代器
实现了迭代器协议的对象。
可迭代协议
可迭代对象必须实现@@iterator方法,意思是对象(或者它的原型链上的某个对象)必须有一个键为@@iterator的属性,可以通过Symbol.iterator访问该属性。
[Symbol.iterator]是一个无参的函数,该函数返回一个符合迭代器协议的对象。
内置可迭代对象:Array、String、Map、Set、TypedArray,因为他们每个prototype对象都实现了@@iterator方法。
Array.prototype[@@iterator]()
TypedArray.prototype[@@iterator]()
String.prototype[@@iterator]()
Map.prototype[@@iterator]()
Set.prototype[@@iterator]()
Map实例的方法:
迭代器协议
一个对象要成为迭代器,要实现一个拥有以下语义的next()方法:
next()
- 是一个无参数或者接受一个参数的函数。
- 返回一个对象,且该对象必须符合IteratorResult接口。该对象必须有两个属性:done和value。
- done:可选,没有指定则为false。
如果迭代器能够生成序列中的下一个值,则返回false。
如果迭代器已经将序列迭代完毕,返回true,此时value可选。 - value:可选,没有指定为undefined。表示迭代器返回的值。
如果返回没有任何属性的对象,等价于{done:false,value:undefined}
总结
可迭代对象可以进行for…of循环,解构,展开语法,yield*。普通对象可以通过实现可迭代协议,使其可进行for … of循环。
迭代协议可以定制对象的迭代行为,分为两个协议:
1.可迭代协议:为对象或对象的原型对象,添加方法[Symbol.iterator] (){},该方法返回符合迭代器协议的对象。
2.迭代器协议:实现了next()方法的对象,next()方法返回一个对象: {done:false ,value:‘xxx’}
{done:false,value:‘xxxx’} //继续迭代
{done:true} //已结束
迭代器的两种实现方式:
1.使用生成器
2.自己实现 对象,next方法
实现普通对象的可迭代性
let obj = {
name: "Monica",
age: 18,
};
obj[Symbol.iterator] = function () {
let arr = Object.entries(this);
let index = 0;
return {
next() {
if (index < arr.length) {
const str = `属性名:${arr[index][0]},属性值:${arr[index][1]}`;
index++;
return {
done: false,
value: str,
};
} else {
return { done: true };
}
},
};
};
for (const p of obj) {
console.log(p);
}
//属性名:name,属性值:Monica
//属性名:age,属性值:18
一个相关的面试题
要求在不改变代码的情况下,让代码输出正确的内容
var [a,b] = {
a:3,
b:4
}
console.log(a,b);//3,4
//方法一:
Object.prototype[Symbol.iterator] = function () {
return Object.values(this)[Symbol.iterator]();
};
//方法二:使用生成器实现
Object.prototype[Symbol.iterator] = function* () {
yield* Object.values(this);
};
var [a, b] = {
a: 3,
b: 4,
};
console.log(a, b);//3,4