深入浅出JS-19 手把手写个迭代器

深入浅出JS-19 手把手写个迭代器,第1张

迭代器

迭代器是一个特殊的对象,可以帮助我们遍历另一个数据结构(数组 链表 映射表等

1. 基本结构

JS中迭代器是一个具体的对象,这个对象有一个next函数:函数无参数或者有一个参数,返回一个拥有以下两个属性的对象

done(boolean):如果迭代器可以产生序列中的下一个值,则为 false;如果迭代器已将序列迭代完毕,则为 true。value(任意类型):迭代器返回的值
const iterator = {
	next() {
		reutrn { done: false, value:'任意类型' }
	}
}
2. 使用方法

借助迭代器来遍历另一个数据结构

/*定义迭代器来遍历names数组*/

// 1 定义数组
const names = ["aaa", "bbb", "ccc"];

// 2 定义该数组对应的迭代器
let index = 0;
const namesIterator = {
  next() {
    if (index < names.length) {
      return { done: false, value: names[index++] };
    } else {
      return { done: true, value: undefined };
    }
  },
};

// 3 用迭代器来遍历数组
console.log(namesIterator.next()); // { done: false, value: 'aaa' }
console.log(namesIterator.next()); // { done: false, value: 'bbb' } 
console.log(namesIterator.next()); // { done: false, value: 'ccc' } 
console.log(namesIterator.next()); // { done: true, value: undefined }

如果对每个对象都定义一个迭代器,太麻烦,所以构造一个迭代器生成函数,上面代码可以改写为:

// 生成迭代器函数
function createIterator(obj) {
  let index = 0;
  return (iterator = {
    next() {
      if (index < obj.length) {
        return { done: false, value: obj[index++] };
      } else {
        return { done: true, value: undefined };
      }
    },
  });
}

const names = ["aaa", "bbb", "ccc"];
const namesIterator = createIterator(names);
3. 应用—构造可迭代对象

普通对象+迭代器+index = 可迭代对象
可迭代对象的要求是必须实现 @@iterator 方法,在代码中我们使用 Symbol.iterator表示
可迭代对象有诸多语法糖可以使用,

// 可迭代对象
const iterableObj = {
  // 普通对象
  obj: ["aaa", "bbb", "ccc"],

  // 
  [Symbol.iterator]() {
    let index = 0;
    return {
      next:() => {
        if (index < this.obj.length) { // 注意this的绑定
          return { done: false, value: this.obj[index++] };
        } else {
          return { done: true, value: undefined };
        }
      },
    };
  },
};

// 1 调用[Symbol.iterator]函数
const iterator = iterableObj[Symbol.iterator](); //生成一个迭代器
console.log(iterator.next()); 
console.log(iterator.next());

// 2 for-of遍历要求对象为可迭代对象
// for-of 是迭代器.next()的语法糖, 有done是否为true看判断循环是否终止(可迭代对象的应用1)
for(const item of iterableObj){
  console.log(item);
}

可迭代对象的应用

1 for-of2 展开语法 …3 数组解构语法4 创建一些其他对象 Set5 创建数组 Array.from5 其他API Promise.all()注意:object不是可迭代对象,但是用别的方法实现了展开语法和解构赋值

原生可迭代对象:

array map set arguments,可用for...of 遍历,说明对象原型上有Symbol.iterator方法可以通过Array.prototype[Symbol.iterator]验证 5. 案例—构造可迭代对象

构造一个书包类,包中有名称、颜色、当前放入的物品;包中可以新添加物品;遍历书包,可以依次输出包中物品

class Bag {
  constructor(name, color, items = []) {
    this.name = name;
    this.color = color;
    this.items = items;
  }

  addItem(item) {
    this.items.push(item);
  }

  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.items.length) {
          return { done: false, value: this.items[index++] };
        } else {
          return { done: true, value: undefined };
        }
      },
    };
  }
}

const bag = new Bag('lovecode bag', 'red', ['pen', 'paper', 'coins'] );

// 可迭代对象,可以用for...of遍历了
for(const item of bag){
  console.log(item);
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1297937.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-10
下一篇2022-06-10

发表评论

登录后才能评论

评论列表(0条)

    保存