方法对应的不是遍历器生成函数(即会返回一个遍历器对象),解释引擎将会报错。...的Symbol.iterator方法对应的不是遍历器生成函数,因此报错。...有了遍历器接口,数据结构就可以用for...of循环遍历(详见下文),也可以使用while循环遍历。...# Iterator 接口与 Generator 函数 Symbol.iterator方法的最简单实现,还是使用下一章要介绍的 Generator 函数。...v); // red green blue } 上面代码中,空对象obj部署了数组arr的Symbol.iterator属性,结果obj的for...of循环,产生了与arr完全一样的结果。
对数组['a', 'b']执行这个函数,就会返回该数组的遍历器对象(即指针对象)it。 指针对象的 next 方法,用来移动指针。开始时,指针指向数组的开始位置。...如果Symbol.iterator方法对应的不是遍历器生成函数(即会返回一个遍历器对象),解释引擎将会报错 var obj = {}; obj[Symbol.iterator] = () => 1;...[...obj] // TypeError: [] is not a function 上面代码中,变量obj的Symbol.iterator方法对应的不是遍历器生成函数,因此报错。...5.Iterator 接口与 Generator 函数 Symbol.iterator方法的最简单实现,还是使用下一章要介绍的 Generator 函数。...v); // red green blue } 上面代码中,空对象obj部署了数组arr的Symbol.iterator属性,结果obj的for...of循环,产生了与arr完全一样的结果。
在ES6之前,JavaScript中的变量声明使用var关键字,它具有函数作用域而不是块级作用域。这意味着使用var声明的变量可以在其所在的函数内部任何位置访问,而不仅仅是在声明的块级作用域内。...4、使用箭头函数绑定外部this值箭头函数可以绑定外部 this 值,这是因为箭头函数没有自己的 this 上下文。箭头函数的 this 值继承了它所在上下文的 this 值。...当我们在箭头函数中使用 this 时,它指向的就是箭头函数所在的上下文中的 this 值。...由于箭头函数继承了它所在上下文的 this 值,因此在箭头函数中我们可以访问到组件实例的 this 值。 三、模板字符串在ES6中,模板字符串是一种特殊的字符串语法,使用反引号(`)来包裹字符串内容。...= ...arr1, ...arr2;console.log(combinedArray); // 输出:1, 2, 3, 4, 5, 6在上面的例子中,我们使用扩展运算符将两个数组 arr1 和 arr2
迭代器简单使用 通过可迭代对象中的迭代器工厂函数 Symbol.iterator来生成迭代器。...const arr = [] console.log(arr) const arr = [1, 2, 3] const iter1 = arr[Symbol.iterator]() // 通过迭代器工厂函数...但是,上面的说法并不是很准确,并不是迭代器下一个值 value为 undefined时,就完成的。还需要判断是不是真的没有值,还是是可迭代对象里就有一个值为 undefined。...const arr = [1, 2, 3, undefined] const iter1 = arr[Symbol.iterator]() // 通过迭代器工厂函数` Symbol.iterator...const arr = [1, 2, 3] const iter1 = arr[Symbol.iterator]() // 通过迭代器工厂函数` Symbol.iterator`来生成迭代器。
创建Symbol:可以使用Symbol()函数来创建一个Symbol。...示例:// 创建Symbollet symbol = Symbol();console.log(typeof symbol); // 输出: "symbol"在上面的示例中,我们使用Symbol()函数创建了一个新的...通过使用nameSymbol作为属性键,我们可以访问到对应的属性值。Symbol的描述符:创建Symbol时,可以为其添加一个可选的描述符(字符串类型),用于描述该Symbol的用途或含义。...示例:// 内置的Symbol值let arr = [1, 2, 3];console.log(arr[Symbol.iterator]); // 输出: [Function: values]let obj...我们访问了数组arr的内置Symbol值Symbol.iterator,以及对象obj的内置Symbol值Symbol.toStringTag。
然后,函数体中一般执行的是异步操作,比如发起Ajax请求,或者开启定时器等。 3、异步操作成功时,调用resolve回调函数,异步操作失败时,调用reject回调函数。...Promise的状态为rejected的情况; 6、上面说到,在异步操作成功或者失败的时候,会调用resolve和reject函数,在这两个回调函数中可以传入参数,这个参数可以直接带入到then中两个匿名函数的参数中使用...typeof运算符的结果,表明变量s是 Symbol 数据类型,而不是字符串之类的其他类型。 注意,Symbol函数前不能使用new命令,否则会报错。...当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法。...原因在于,这些数据结构原生部署了Symbol.iterator属性(详见下文),另外一些数据结构没有(比如对象)。凡是部署了Symbol.iterator属性的数据结构,就称为部署了遍历器接口。
背景 遍历数组的时候,我相信大多数人已经用上ES6的for...of语法了: const arr = [1, 2, 3] for (const item of arr) { console.log...详细的内容请访问MDN查阅,我这里做一个总结: 可迭代对象需要有一个Symbol.iterator函数属性,返回迭代器对象。 迭代器对象需要有一个next函数属性,返回迭代结果。...所以说,根据这些,我们可以想到一个简化代码的思路,就是让range返回的对象本身也是一个迭代器,当调用Symbol.iterator时返回this: function range(end) {...} } } for (const i of range(5)) { console.log(i) } // 0 1 2 3 4 已经优化了很多了,但是这样还是不够简练,于是引出我们下文要说的内容...(r === itor) // true 和我们自己实现的时候类似,它调用Symbol.iterator时返回的是this。
遍历原理当我们使用for...of循环或者手动调用next()方法时,迭代器会按照预定的顺序依次返回集合中的每个元素。...使用示例示例一:let arr = [1, 2, 3];let iterator = arr[Symbol.iterator]();console.log(iterator.next()); // {...,我们首先通过调用数组arr上的Symbol.iterator方法获取到数组的默认迭代器。...该函数返回一个包含next()方法的对象,每次调用next()方法时,会依次返回数组中的每个元素。...通过使用yield关键字,我们可以在函数执行过程中暂停和恢复,并且可以将异步操作以同步方式编写和理解。3. 原理当我们调用生成器函数时,实际上并不会立即执行函数体内部的代码。
(x); // → 10 console.log(rest); // → [20, 30] 在上述代码中,arr中的第一项分配给x,其余元素分配给rest变量。...一个可异步迭代对象中包含Symbol.asyncIterator属性(而不是Symbol.iterator),其功能为返回一个异步迭代器。...通常,您希望使用finally()作为最后一个链,但是在某些情况下,例如在发出HTTP请求时,最好将另一个catch()链接起来,以处理finally()中可能出现的错误。...当您想用函数解析模板文字时,带标记的模板就派上用场了。...模板文字调用了一个标记表达式(函数):修改字符串中的变量部分。
以上数据类型,都有 Symbol.iterator 属性,属性值是一个函数,执行这个函数就会返回一个迭代器。这个迭代器就有 next 方法可顺序迭代子元素。...Symbol.iterator 属性本身是一个函数,这个函数是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。...方法对应的不是遍历器生成函数(即会返回一个遍历器对象),解释引擎将会报错。...: undefined is not a function // 个人理解:报这个错是因为,执行for of循环的时候,会去遍历器生成函数Symbol.iterator的返回的对象中寻找next方法来执行...(item); // red green blue } 上面代码中,空对象 obj 部署了数组 arr 的 Symbol.iterator 属性,结果 obj 的 for…of 循环,产生了与 arr
ES6中规定对象的Symbol.iterator属性指向该对象的默认迭代器方法,当对象进行for...of..遍历迭代时,会调用对象的Symbol.iterator方法,返回该对象的默认迭代器。...下面是数组的迭代器接口使用示例: var arr = [10, 2, 3, 4, 5]; var it = arr[Symbol.iterator](); // 调用数组arr的迭代器接口方法,获取数组的迭代器对象...从ES6开始,从一个iterable中提取迭代器的方法是:iterable必须支持一个函数,其名称是专门的ES6符号值Symbol.iterator。调用这个函数时,它会返回一个迭代器。...for..of循环会自动调用它的Symbol.iterator函数来构建一个迭代器。当然也可以手工调用这个Symbol.iterator函数,然后使用它返回的迭代器。...对于上例中arr数组的手工创建迭代器: var arr = [10, 2, 3 , 5, 6]; var it = arr[Symbol.iterator](); // 注意,这里要调用(Symbol.iterator
在第一段代码中我们遍历的是一个数组,第二段遍历的是一个字符串,我们采用了不同的方法,也就是说我们在面对不同数据结构时往往会采取不同的遍历方式。...在 JavaScript 中原有的表示“集合”的数据结构,主要是 Array 和 Object ,而在 ES6中又新增了 Map和 Set 两种,同时我们还可以组合使用这些数据结构。...Symbol.iterator 属性本身是一个函数,就是当前数据结构默认的遍历器生成函数,执行这个函数,就会返回一个迭代器对象。...Iterator 原生应用场景 有些对象我们并没有为它们部署 Iterator 接口,但是仍然可以使用 for...of 进行遍历。这是因为在ES6中有些对象已经默认部署了这个接口。...解构赋值 对可迭代对象进行解构赋值时,会默认调用 Symbol.iterator 方法 let map = new Set().add('a').add('b'); let [x, y] = map console.log
高程给出了解释: 迭代之前需要事先知道如何使用数据结构。 数组中的每一项都只能先通过引用取得数组对象, 然后再通过[]操作符取得特定索引位置上的项。并且,这种情况并不适用于所有数据结构。...即: for 循环不适用遍历所有数据结构; ES5 发布了 forEach ,并没有做出任何改善,反而也是弊端多多: 不能使用 break 语句中断循环; 不能使用 return 语句返回到外层函数;...]()); // ArrayIterator {} ES6 默认的 Iterator 接口部署在数据结构的 Symbol.iterator属性上,该属性本身是一个函数,代表当前数据结构默认的遍历器生成函数...执行该函数 [Symbol.iterator](),会返回一个遍历器对象。只要数据结构拥有 Symbol.iterator属性,那么它就是 “可遍历的” 。...]() { return this; } } 很神奇,不是吗?
JavaScript 中除了 Array 之外,ES6 还新增加了 Map、Set 结构,当我们需要操作这些数据时,就需要一种统一的接口来处理这些不同的数据结构。...了解生成器函数(Generator)的可能不会陌生,同样的当你执行一个生成器函数也会得到一个迭代器对象,但是要区分 生成器和迭代器不是一个概念。...Iterator 接口遍历 解构赋值 数组、Set、Map 解构赋值时,会默认调用 Symbol.iterator 方法。...]() for (const id of r1) { console.log(id); // 0,1,2,3 } 基于生成器函数的迭代器实现 使用生成器函数(Generator)实现是最简单的,只要使用...下一节我们将会讲解异步迭代器在 Node.js 中的使用,欢迎关注。
简单的来说我们迭代循环一个可迭代对象,不是一次返回所有数据,而是调用相关方法分次进行返回。...迭代器是帮助我们对某个数据结构进行遍历的对象,这个object有一个next函数,该函数返回一个有value和done属性的object,其中value指向迭代序列中当前next函数定义的值。...只要实现符合要求的next函数,该对象就是一个迭代器。相当遍历数据结构元素的指针,类似数据库中的游标。...> index arr.length ?...}, } }, } // 测试 for (const item of obj) { console.log(item) if (item === '222') break } 在上面两个模拟迭代器示例中
方法,再调用返回的next方法,最后得到当前的值 我们可以在控制台看下 数组是有这个Symbol.iterator属性的 从以上迭代器特征中,我们可以得知,数组是通过一个Symbol.iterator...yield这样的关键字 实际上这就是内部函数的状态机,当你使用用生成器时,你调用next就会返回一个对象,并且像迭代器一样返回{value: xxx, done: false}因此在使用上,我们必须认清...当你使用 ... gtest[Symbol.iterator]().next(); gtest[Symbol.iterator]().next() gtest[Symbol.iterator]().next...本质上是通过生成器对象的prototype的Symbol.iterator连接了起来 生成器函数的return 当我们在生成器函数内部return时,那么当调用next迭代完所有的值时,继续调用next...生成器函数调用返回的是一个迭代器,具备迭代器所有特性,yield这个状态机只能在生成器函数内部使用 以实际例子对对象扩展支持迭代器特性,如果需要支持迭代器特征,那么必须原型上扩展Symbol.iterator
Hook 开发组件的过程中如何提高性能。...useCallback 优化组件 如果已经用了 memo ,当遇到下面这种场景时,同样会触发子组件渲染。...memo 不是会判断 name 变化了,才会更新吗?...useMemo 优化 我们定义了一个total函数,内部使用 1 填充了100次,通过 reduce 计算总和,经过测试发现点击 Increase按钮后,只会执行 total1 ,不会执行 total2...,会返回一个 memoized 值,需要注意的是,函数内必须有返回值 第二个参数会依赖值,当依赖值更新时,会从新计算。
其实for of 并不是真的强大,他只是一种ES6新的语法而已。 并不是所有的对象都能使用 for of,只有实现了Iterator接口的对象才能够使用 for of 来进行遍历取值。...这是因为在 ES6中有些对象已经默认部署了此接口,不需要做任何处理,就可以使用 for of 来进行遍历取值。 不信?咿,你好难搞,我不要你说 - 信,我要我说 - 信。...数组 //数组 var arr=[100,200,300]; var iteratorObj= arr[Symbol.iterator]();//得到迭代器方法,返回迭代器对象 console.log...例如:Set、Map、Array.from 等 //为了证明,先把一个数组的默认迭代器给覆盖掉 var arr=[100,200,300]; arr[Symbol.iterator]=function...); //调用 Array.from方法 Array.from(arr); yield* 关键字 yield*后面跟的是一个可遍历的结构,执行时也会调用迭代器函数。
领取专属 10元无门槛券
手把手带您无忧上云