js中的迭代器,可迭代对象

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));
  • 测试
    js中的迭代器,可迭代对象_第1张图片
  • 结论
    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 将不可迭代的数据转换可迭代数据

  1. 尝试使用for...of
    在这里插入图片描述
  2. 直接修改对象原型属性

开发中,不会直接去修改原型。

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.valuesArray.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"]

参考

  • ES6可迭代对象与迭代器的理解
  • MDN

你可能感兴趣的:(js中的迭代器,可迭代对象)