用JavaScript遍历器iterator实现指针结构;为对象实现iterator接口
2021.08.165 min read
原创声明:未经允许,禁止转载
虽然String
, Array
, Map
, Set
和一些DOM collection
类型都自带iterator实现,很多时候我们还需要一些自定义的iterator来实现一些自定义的功能和处理。
JavaScript遍历器(iterator)接口可以为不同的数据结构实现统一的访问机制, 因此通过iterator我们可以为自定义的数据结构(比如包含Map成员的数组)部署统一的接口来实现遍历操作。并且通过定义iterator的方式遍历结构我们可以保证遍历/数据处理的顺序。
(iterator接口的实现主要通过for...of结构来使用)
比如:
实现指针结构:
function Node(value) {
this.value = value;
this.next = null;
}
Node.prototype[Symbol.iterator] = function () {
let current = this;
return {
next() {
if (current) {
let value = current.value;
current = current.next; // 将指针指向下一个instance
return { done: false, value: value }; //返回当前instance的值
} else {
return { done: true };
}
},
};
};
let one = new Node(1);
let two = new Node(2);
let three = new Node(3);
one.next = two;
two.next = three;
for (const iterator of one) {
console.log(iterator);
}
// 1
// 2
// 3
为对象实现iterator接口
let obj = {
data: [1, 2, 3, 4, 5],
};
obj[Symbol.iterator] = function () {
let index = 0;
const data = this.data;
return {
next() {
return data[index]
? { value: data[index++], done: false }
: { done: true };
},
};
};
let test = obj[Symbol.iterator]();
console.log(test.next()); // { value: 1, done: false }
for (const iterator of obj) {
console.log(iterator);
}
// 1
// 2
// 3
// 4
// 5
为类似数组的对象简单添加iterator接口结构
let obj = {
0: "a",
1: "b",
2: "c",
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator],
};
for (const iterator of obj) {
console.log(iterator);
}
// a
// b
// c
但是对于像下面一样属性值不是数组的index结构的普通对象,则不能够简单部署引用数组的Symbol.iterator
let obj = {
a: "a",
b: "b",
c: "c",
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator],
};
for (const iterator of obj) {
console.log(iterator);
}
// undefined
// undefined
// undefined