js迭代器iterator

iterator(迭代)一般很少直接使用, 但是却是很常用很重要的功能.
例如 :
对象的扩展运算符(...)内部其实是调用了 Iterator 接口。
在es6 中统一了遍历的接口 Iterator,Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for...of循环。
字符串也可以使用扩展运算符

var arr = [..."hello"];
console.log(arr)
// ["h", "e", "l", "l", "o"]

rest运算符, 与扩展运算符是逆运算

扩展运算符:数组=>分割序列

// arguments变量的写法
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}
​
// rest参数的写法
const sortNumbers = (...numbers) => numbers.sort();

rest运算符:分割序列=>数组
rest可以代替arguments变量

回到主题, 迭代
Symbol.iterator 为每一个对象定义了默认的迭代器。

描述

当需要对一个对象进行迭代时(比如开始用于一个for..of循环中),它的@@iterator方法都会在不传参情况下被调用,返回的迭代器用于获取要迭代的值。

一些内置类型拥有默认的迭代器行为,其他类型(如 Object)则没有。下表中的内置类型拥有默认的@@iterator方法:

  • Array.prototype[@@iterator]()
  • TypedArray.prototype[@@iterator]()
  • String.prototype[@@iterator]()
  • Map.prototype[@@iterator]()
  • Set.prototype[@@iterator]()

更多信息请参见迭代协议。

js中对象分为可迭代和不可迭代 如果是可迭代哪它就会有一个[Symbol.iterator] 函数

这个函数就是对象的迭代器函数,如用for of 如果遍历的对象没有这个迭代方法那么就会报错.

for of 传入的是可迭代对象,但是如何吧一个不可迭代的对象变为可迭代的对象呢!很简单就是自己写一个[Symbol.iterator]函数。

let obj = {
   a: 1,
   b: 2
}
obj[Symbol.iterator] = function(){
   let  keys = Object.keys(obj) 
   let len = keys.length;
   let n = 0;
   // 返回对象 每次迭代会自动调用对象里面的next方法
   return {
       next() {
          //  返回值有value和done
          return n < len ? {
               value: { k: keys[n], v: obj[keys[n++]] },
               done: false 
          }: { done: true }
       }
   }
}

你以为迭代就这么简单的结束了吗?现在再讲一个新东西 yield

. yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。

. yield关键字实际返回一个IteratorResult(迭代器)对象,它有两个属性,value和done,分别代表返回值和是否完成。

. yield无法单独工作,需要配合generator(生成器)的其他函数,如next,懒汉式操作,展现强大的主动控制特性。

yield自定义一个迭代器

var myIterable = {}
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};
[...myIterable] // [1, 2, 3]


// 为不可迭代的对象添加迭代器
let obj = {
    a: 1,
    b: 2
}
obj[Symbol.iterator] = function* () {
    let keys = Object.keys(obj);
    //取到key值的长度
    let len = keys.length;
    //定义循环变量
    let n = 0;
    //条件判断
    while (n < len) {
        yield { k: keys[n], v: obj[keys[n++]] };
    }
}
//返回的是个对象的key和value
for (let { k, v } of obj) {
    console.log(k, v);
}

function* () {} 这种函数名字叫 generator函数, 生成器函数, 下一篇再重点讲这个哈.

你可能感兴趣的:(js迭代器iterator)