<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Iterator</title>
</head>
<body>
<script>
//迭代器的简单实现
let it = makeIterator(['a', 'b']);
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
/*
{ value: 'a', done: false }
{ value: 'b', done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }
*/
function makeIterator(array) {
let nextIndex = 0;
return {
next() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{value: undefined, done: true};
}
}
}
//默认Iterator接口
/*
Iterator接口的目的,就是为所有的数据结构,提供了一种统一的访问机制,即for...of循环(该循环方式需要继承Iterator的对象
任何数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”
return {value:"",done:false} done:true语句很关键,是结束标志 中done为true时迭代会停止
*/
console.log("=============默认Iterator接口================");
const obj = {
[Symbol.iterator]: function () {
return {
next() {
return {
value: 1,
done: true
}
}
}
}
};
let objIterator = obj[Symbol.iterator]();
console.log("objIterator.next",objIterator.next());
for (let o of obj) {
console.log("iterator_Obj", o);
}
//类的形式生成
console.log("=============类的形式生成================");
class RangeIterator {
constructor(start, stop) {
this.value = start;
this.stop = stop;
}
[Symbol.iterator]() {
return this
}
next() {
var value = this.value;
if (value < this.stop) {
this.value++;
return {done:false, value: value}
}
return {done:true, value: undefined}
}
}
function range(start, stop) {
return new RangeIterator(start, stop);
}
for (let value of range(0, 3)) {
console.log("class: ",value);
}
//通过遍历器实现指针结构的例子
console.log("=============通过遍历器实现指针结构的例子================");
function PrototypeObj(value) {
this.value = value;
this.next = null;
}
PrototypeObj.prototype[Symbol.iterator] = function () {
let iterator = {next: next};
let current = this;
debugger
function next() {
if (current) {
let value = current.value;
current = current.next;
return {done:false, value: value};
}else{
return {done: true}
}
}
return iterator;
};
let one = new PrototypeObj(1);
let two = new PrototypeObj(2);
let three = new PrototypeObj(3);
one.next = two;
two.next = three;
for (let i of one) {
console.log("PrototypeObj",i);//1,2,3
}
// 原生具有Symbol.iterator属性的数据结构有
console.log("=============原生具有Symbol.iterator属性的数据结构有================");
/*
* Array、Map、Set、String、TypedArray、函数的arguments对象、NodeList对象*/
let arr = ['a', 'b', 'c'];
let arrIter = arr[Symbol.iterator]();
console.log(arrIter.next());//a,b,c
//对象添加Iterator接口的例子
console.log("=============对象添加Iterator接口的例子================");
let objectInfo = {
data: ['hello', 'world'],
[Symbol.iterator]() {
const self = this;
let index = 0;
return {
next() {
if (index < self.data.length) {
return {
value: self.data[index++],
done:false
}
}else{
return {value:undefined, done: true}
}
}
}
}
}
for (let oooo of objectInfo) {
console.log("对象添加Iterator接口的例子",oooo);//对象添加Iterator接口的例子 hello ,对象添加Iterator接口的例子 world
}
//类似数组的对象调用数组的Symbol.iterator方法的例子
console.log("=============类似数组的对象调用数组的Symbol.iterator方法的例子================");
let iterableArr = {
0: "a",
1: "b",
2: "c",
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let arrayObject of iterableArr) {
console.log("iterableArr", arrayObject);//a,b,c
}
//最简单的实现,使用Generator函数
console.log("=============最简单的实现,使用Generator函数================");
let myIterable = {
[Symbol.iterator]: function* () {
yield 1;
yield 2;
yield 3;
}
}
let a = [...myIterable];
console.log(a);//1,2,3
let objSimple = {
* [Symbol.iterator]
() {
yield 'hello';
yield 'world';
}}
for (let oSimple of objSimple) {
console.log(oSimple)//hello,world
}
//for...in 与 for...of 的区别
//for...in主要用于遍历 键名
//for...of主要用于遍历 键值
</script>
</body>
</html>
网友评论