1、可迭代对象
- Set
- Map
- String
- Array
- Arguments
- NodeList
1.1 判断是否拥有可迭代能力
- 当一个数据具备
Symbol.iterator
属性的时候,才可以用for...of
进行迭代。
console.log(Array.prototype.hasOwnProperty(Symbol.iterator));
console.log(Set.prototype.hasOwnProperty(Symbol.iterator));
- 测试
- 结论
Array.prototype[Symbol.iterator]
是一个函数,执行完函数返回的一个对象,对象拥有next
方法。
1.2 手动实现迭代器
const createIterator = items => {
const keys = Object.keys(items);
const len = keys.length;
let pointer = 0; // 当前的指针位置
return {
next() {
const done = pointer >= len;
const value = !done ? items[keys[pointer++]] : undefined; // 如果当前指针位置小于总长度
return {
value,
done
}
}
}
}
- 测试数组
let list = [1,2,3,4];
let listIterator = createIterator(list);
listIterator.next()
listIterator.next()
listIterator.next()
listIterator.next()
listIterator.next()
// logout
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 4, done: false }
{ value: undefined, done: true }
- 测试对象
let obj = {name:'小李',id:'123'};
let objIterator = createIterator(obj);
objIterator.next()
objIterator.next()
objIterator.next()
// logout
{ value: '小李', done: false }
{ value: '123', done: false }
{ value: undefined, done: true }
1.3 为什么数据是可迭代对象,却不能使用next()
可迭代对象不是迭代器,迭代器才有next()方法。
1.4 将不可迭代的数据转换可迭代数据
- 尝试使用
for...of
- 直接修改对象原型属性
开发中,不会直接去修改原型。
Object.prototype[Symbol.iterator] = function() {
const self = this;
const keys = Object.keys(self);
const len = keys.length;
let pointer = 0;
return {
next() {
const done = pointer >= len;
const value = !done ? self[keys[pointer++]]: undefined;
return {
done,
value
}
}
}
}
let obj = {name: '小李', gender: '男'};
let objItem = obj[Symbol.iterator]();
console.log(objItem.next());
for (const item of obj) {
console.log(item)
}
2、Array.prototype.keys()
- 索引迭代器会包含那些没有对应元素的索引
var arr = ["a", , "c"];
var sparseKeys = Object.keys(arr);
var denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2']
console.log(denseKeys); // [0, 1, 2]
3、Array.prototype.values()
values()
方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值。
const array1 = ['a', 'b', 'c'];
const iterator = array1.values();
for (const value of iterator) {
console.log(value);
} // a b c
Array.prototype.values
是Array.prototype[Symbol.iterator]
的默认实现。
一次性
:数组迭代器是一次性的,或者说临时对象
var arr = ['a', 'b', 'c', 'd'];
var iterator = arr.values();
for (let letter of iterator) {
console.log(letter);
} //"a" "b" "c" "d"
for (let letter of iterator) {
console.log(letter);
} // undefined
4、Array.prototype.entries()
entries()
方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
const array1 = ['a', 'b', 'c'];
const iterator1 = array1.entries();
console.log(iterator1.next().value);
// expected output: Array [0, "a"]
console.log(iterator1.next().value);
// expected output: Array [1, "b"]