最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 如果又忘了迭代器和生成器就来看这篇文章

    正文概述 掘金(Juga酸不酸君)   2020-12-14   552

    前言

    首先要回顾迭代器和生成器的话,心中要有一个概念,迭代器其实可以看成一种规范,类似promise+规范的的东西,迭代器是一个函数,一个符合迭代器规范的函数。

    那么这个规范是啥?个人简单的理解就是 迭代器函数返回一个含有next方法的对象,next方法返回一个包含 value done 属性的对象。只要符合这个规范的函数 都可以称之为迭代器。

    那么什么是生成器?个人理解就是 function* 其实也是一个函数,只是这个函数比较特殊,该函数返回一个generator对象,该对象也就是上面说说的迭代器函数返回的对象。只是此时function是隐式的返回。而迭代器函数是显式的返回带有next方法的对象。

    迭代器

    迭代器说明

    下面这个例子就是一个迭代器例子,其实迭代器next方法的调用可以看成指针的移动,每调用一次next,指针就移向数据结构中的下一个数据,返回 { value: 值, done: 布尔值(遍历结束没)}。遍历完了后不管调用几次next,都是返回{ value: undefined, done: true }。

    var it = makeIterator(['a', 'b']);
    it.next() // { value: "a", done: false }
    it.next() // { value: "b", done: false }
    it.next() // { value: undefined, done: true }
    function makeIterator(array) {
      var nextIndex = 0;
      return {
        next: function () {
          return nextIndex < array.length ?
            { value: array[nextIndex++], done: false } :
            { value: undefined, done: true };
        }
      };
    }
    

    迭代器接口

    其实在JS里已经有很多对象是可迭代的。比如 常用的Array Map Set String,这些类型的实例里都有一个名为Symbol.iterator的接口函数,可直接调用该函数返回迭代器。这些对象不用任何处理就可以被 for...of 循环遍历(可用break),而普通的对象是不能的(除非我们人为的给对象加上Symbol.iterator接口)。

    如果又忘了迭代器和生成器就来看这篇文章

    let arr = ['a', 'b', 'c'];
    // 可直接调用Symbol.iterator接口
    let iter = arr[Symbol.iterator]();
    iter.next() // { value: 'a', done: false }
    iter.next() // { value: 'b', done: false }
    iter.next() // { value: 'c', done: false }
    iter.next() // { value: undefined, done: true }
    
    

    练手题

    针对上面说的普通对象是没法被遍历的,那么如何实现 obj={a: '1', b: '2'} let arr = [...obj] 输出 [1, 2]。

    其实这题就是考察解构符号,对象不能在数组里面解构。会报错 TypeError: obj is not iterable,那么只要把这个对象添加上Symbol.iterator 接口函数就可以了。

    
    function Valuemaker(obj) {
      let index = 0;
      return {
        next: function () {
          
          if (index < Object.keys(obj).length) {
            return { value: obj[Object.keys(obj)[index++]], done: false}
          }
          return { done: true }
        }
      }
    }
    
    let  obj = {a: 1, b: 2, c: 3};
    // 让obj拥有Sym接口
    obj[Symbol.iterator] = function () {
      return Valuemaker(obj);
    }
    let it = Valuemaker(obj);
    
    

    生成器

    示例说明

    生成器其实也是个函数,只是写的方式为 function* 可以生成generator生成对象。函数在调用对象的next方法时才会执行。搭配yield使用。generator需要注意的是在return 的前一个返回值,done就已经变成了true。next(参数)可以传值。作为上一个yield的返回值。

    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    var hw = helloWorldGenerator();
    
    hw.next()
    // { value: 'hello', done: false }
    hw.next()
    // { value: 'world', done: false }
    hw.next()
    // { value: 'ending', done: true }
    hw.next()
    // { value: undefined, done: true }
    
    

    练手题

    以下输出啥?关键的地方在于 当next(传参)的时候,这个传参相当于上一个yield的返回值,注意如果没有传参的话,yield的返回值一定是undefined

    还有要注意的点是由于 next ⽅法的参数表示上⼀个 yield 语句的返回值, 所以第⼀ 次使⽤ next ⽅法时, 不能带有参数。!!!!

    function* foo(x) {
    var y = 2 * (yield (x + 1));
    var z = yield (y / 3);
    return (x + y + z);
    } v
    ar a = foo(5);
    a.next() // ?
    a.next() // ?
    a.next() // ?
    var b = foo(5);
    b.next() // ?
    b.next(12) // ?
    b.next(13) // ?
    
    

    以下输出啥?

    function* foo() {
      yield 1;
      yield 2;
      yield 3;
      yield 4;
      yield 5;
      return 6;
    }
    for(let v of foo()) {
      console.log(v);
    }
    
    // 1 2 3 4 5
    //⼀旦 next ⽅法的返回对象的 done 属性为 true , for...of 循环就会中⽌
    

    用生成器写一个斐波那契函数

    function* fibo() {
      yield 0;
      yield 1;
      let [pre, cur] = [0, 1];
      for(;;) {
        [pre, cur] = [cur, pre + cur];
        yield cur;
      }
    }
    
    let a = fibo();
    
    for (let v of a) {
      if (v > 100) break;
      console.log(v);
    }
    
    

    起源地下载网 » 如果又忘了迭代器和生成器就来看这篇文章

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元