首页 > 其他分享 >一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)

一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)

时间:2023-11-11 15:22:28浏览次数:34  
标签:遍历 迭代 iterator Symbol value done foo iterable

请问以下JS代码的执行结果是什么?

function control(x) {
  if (x == 3) throw new Error("break");
}
function foo(x = 6) {
  return {
    next: () => {
      control(x);
      return {done: !x, value: x && x--};
    }
  }
}
let x = new Object;
x[Symbol.iterator] = foo;
for (let i of x) console.log(i);

6、5、4、报错

对象x的操作其实是为了让x可以被函数foo通过for of遍历到每一个值,同时因为初始值是6所以是递减的结果,control只是做一个中断操作。

1、什么是迭代器?

迭代器是一个对象,需要满足:对象内部有方法next,next方法要求返回对象{done: true或false, value:值 }
!!!(注意区分:迭代器 和可迭代对象 是不一样的)

2、一个迭代器是如何遍历的?

const arr = ["a","b"]
// 数组默认是一个可迭代对象,就好比题目中的对象x
const iterator = arrSymbol.iterator // 拿到迭代器
console.log(iterator.next());
console.log(iterator.next());
// { value: 'a', done: false }
// { value: 'b', done: false }
// { value: undefined, done: true }

不难看出,value表示每次遍历的值,而done表示遍历是否完成。

3、for...of...补充

for... of...的使用需要是一个可迭代对象,这道题的x,也是因为是一个可迭代对象,所以才可以用的for...of
可以理解为:for..of..就是上面调用iterator.next()的语法糖,直到最后done为true表示遍历完了。...

4、什么是可迭代对象?

如果一个对象,实现了[Symbol.iterator]方法,且这个方法返回一个迭代器(这个方法就是一个生成迭代器的函数,比如题目中的foo函数)

function foo(x = 6) {
  return { // 返回一个迭代器
      next: () => {
          control(x);
          return {done: !x, value: x&&x-- };
      }
  }
}
// x成为可迭代对象
x[Symbol.iterator] = foo

5、得结果

for(let i of x) console.log(i);

既然x是可迭代对象,那他可以用for...of...进行遍历,遍历时会自动去执行foo,foo返回迭代器。
上面也说了for...of...的遍历就是:一次次的调用iterator的next,拿到value,直到next返回的done为true。

function foo(x = 6) {
  return {
    next: () => {
      control(x);
      return {done: !x, value: x && x--};
    }
  }
}

里层next函数调用的x是foo的参数x(闭包),x默认赋值为6,通过题目中的control函数可以知道,x=3的时候,就抛错,结束了。
当x=6,return{ done:!x, value: x && x--}
done为false,value是x && x--
6 && 6, &&前者为true,value结果取后者,return { done:false, value : 6},
然后x--变成5
继续。。。。最后结果
6,5,4,抛错

  1. ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内 2. throw 异常信息;中止程序抛出异常,可用于中止程序

  2. foo 是遍历器生成函数,遍历的时候遇到 throw 就中止遍历和抛出错误

  3. 还是推荐 阮一峰老师 https://es6.ruanyifeng.com/#docs/iterator

标签:遍历,迭代,iterator,Symbol,value,done,foo,iterable
From: https://www.cnblogs.com/longmo666/p/17825939.html

相关文章

  • JavaSE(十八)-迭代器Iterator
    文章目录1.引言2.Iterable3.Iterator4.迭代器遍历5.并发修改异常5.List特有的迭代器ListIterator5.1.特有的方法6.增强for循环1.引言为了方便的处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素.例如删除和获取集合中的元素.该对象就叫做迭代器(......
  • ts symbol 作为属性名
    在TypeScript中,如果你希望在一个对象中使用某个symbol作为属性名,你必须使用中括号[]括起来,并在括号中放入该symbol。  这是因为当你使用symbol作为属性名时,它不是一个字符串,而是一个symbol类型的变量。  因此,正确的写法是[RawSymbol]:'somevalue',这样可以......
  • Symbol.for()
    当我们在不同的模块或文件中需要共享一个特定的Symbol时,可以使用Symbol.for()方法来实现。假设我们有两个模块,分别是module1.js和module2.js。我们希望在这两个模块中使用相同的Symbol来表示一个特定的概念,比如"mySymbol"。在module1.js中,我们可以这样创建和获取Symbol:javascr......
  • Collection&Iterable
    Collection概述Therootinterfaceinthe<i>collectionhierarchy</i>.Acollectionrepresentsagroupofobjects,knownasits<i>elements</i>.Somecollectionsallowduplicateelementsandothersdonot.Someareorderedandothe......
  • Java拾贝第十五天——集合之Iterator迭代器
    虽然foreach循环可以遍历集合输出,但书上提及了一个观点。只要碰到了集合输出的操作,就一定要使用Iterator(迭代器)接口实际上编译器把foreach循环通过Iterator改写为了普通的for循环上述的观点在本文最后一部分会提及。IteratorIterator是专门的迭代输出接口,所谓迭代就是将......
  • 关于Es6的Symbol和访问器
    Symbol和访问器主要是来限制实例成员的如果一个成员暴露出去只让读不让改,我们就可以在类中使用访问器classPerson{getname(){return"HuangBingQuan"}}如果一个成员不让暴露出去(不让外界访问)那就使用Symbol作为属性值functionPerson(){constname=Symbol();retu......
  • How to tell whether a file is a symbolic link in shell script All In One
    HowtotellwhetherafileisasoftsymboliclinkinshellscriptAllInOneshell脚本中如何判断一个文件是否是软链接/软符号链接error软链接自动指向原文件bug❌#软链接$test./test.sh-ef./test-soft-link.sh$echo$?0#硬链接❌$test./test.......
  • Symbol
    概述ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是ES6引......
  • C++迭代器iterator遍历
    iterator是通用的遍历容器的方式通用模板anySet<a...>as;anySet<a...>::iteratorit=as.begin();for(;it!=as.end();it++){cout<<(*it);//即迭代器it指向的元素}四种迭代器正向迭代器,定义方法如下:容器类名::iterator迭代器名;常量正向迭代器,定义......
  • 【HAL 库复盘】自己手动创建工程模版Undefined symbol HAL_NVIC_SetPriority 问题解决
    1问题说明学习自己手动搭建一个STM32HAL库工程模板文件的时候,我发现了有6个错误,6个错误的类型是一样的,其中有3个通过添加hal_rcc.h和hal_gpio.c文件得以解决。所以另外3个我也想到了时缺少了对应的.c文件导致的错误。但是在STM32F1xx_HAL_Driver文件夹中,我没有找到类似如有“rcc......