We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set。这样就需要一种统一的接口机制,来处理所有不同的数据结构。遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
let arr3 = [1, 2, 'kobe', true]; for(let i of arr3){ console.log(i); // 1 2 kobe true }
let str = 'abcd'; for(let item of str){ console.log(item); // a b c d }
function fun() { for (let i of arguments) { console.log(i) // 1 4 5 } } fun(1, 4, 5)
var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]); for (var e of engines) { console.log(e); } // Gecko // Trident // Webkit
function myIterator(arr) { let nextIndex = 0 return { next: function() { return nextIndex < arr.length ? { value: arr[nextIndex++], done: false } : { value: undefined, done: true } } } } let arr = [1, 4, 'ads']// 准备一个数据 let iteratorObj = myIterator(arr) console.log(iteratorObj.next()) // 所有的迭代器对象都拥有next()方法,会返回一个结果对象 console.log(iteratorObj.next()) console.log(iteratorObj.next()) console.log(iteratorObj.next())
① for of循环不支持遍历普通对象
var obj = { a: 2, b: 3 } for (let i of obj) { console.log(i) // Uncaught TypeError: obj is not iterable }
对象的Symbol.iterator属性,指向该对象的默认遍历器方法。当使用for of去遍历某一个数据结构的时候,首先去找Symbol.iterator,找到了就去遍历,没有找到的话不能遍历,提示Uncaught TypeError: XXX is not iterable
Uncaught TypeError: XXX is not iterable
② 当使用扩展运算符(...)或者对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法
let arr1 = [1,3] let arr2 = [2,3,4,5] arr2 = [1,...arr2,6] console.log(arr2) // [1, 2, 3, 4, 5, 6]
function* generatorExample(){ console.log("开始执行") yield 'hello'; yield 'generator'; } // generatorExample() // 这种调用方法Generator 函数并不会执行 let MG = generatorExample() // 返回指针对象 MG.next() //开始执行 {value: "hello", done: false}
Generator 函数是分段执行的,调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: yield后的表达式结果/undefined, done: false/true},再次调用next方法会从上一次停止时的yield处开始,直到最后。
{value: yield后的表达式结果/undefined, done: false/true}
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 }
第一次调用,Generator 函数开始执行,直到遇到第一个yield表达式为止。next方法返回一个对象,它的value属性就是当前yield表达式的值hello,done属性的值false,表示遍历还没有结束。
第二次调用,Generator 函数从上次yield表达式停下的地方,一直执行到下一个yield表达式。next方法返回的对象的value属性就是当前yield表达式的值world,done属性的值false,表示遍历还没有结束。
第三次调用,Generator 函数从上次yield表达式停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。
第四次调用,此时 Generator 函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true。以后再调用next方法,返回的都是这个值。
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
function* generatorExample () { console.log('开始执行') let result = yield 'hello' console.log(result) yield 'generator' } let MG = generatorExample() MG.next() MG.next() // 开始执行 // undefined // {value: "generator", done: false}
没有传值时result默认是undefined,接下来我们向第二个next传递一个参数,看下输出结果是啥?
function* generatorExample () { console.log('开始执行') let result = yield 'hello' console.log(result) yield 'generator' } let MG = generatorExample() MG.next() MG.next(11) // 开始执行 // 11 // {value: "generator", done: false}
我们上文中提到对象没有iterator接口,用for...of遍历时便会报错。
let obj = { username: 'kobe', age: 39 } for (let i of obj) { console.log(i) // Uncaught TypeError: obj is not iterable }
由于 Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。
let obj = { username: 'kobe', age: 39 } obj[Symbol.iterator] = function* myTest() { yield 1; yield 2; yield 3; }; for (let i of obj) { console.log(i) // 1 2 3 }
上面代码中,Generator函数赋值给Symbol.iterator属性,从而使得obj对象具有了 Iterator 接口,可以被for of遍历了。
function* sendXml() { // url为next传参进来的数据 let url = yield getNews('http://localhost:3000/news?newsId=2');//获取新闻内容 yield getNews(url);//获取对应的新闻评论内容,只有先获取新闻的数据拼凑成url,才能向后台请求 } function getNews(url) { $.get(url, function (data) { console.log(data); let commentsUrl = data.commentsUrl; let url = 'http://localhost:3000' + commentsUrl; // 当获取新闻内容成功,发送请求获取对应的评论内容 // 调用next传参会作为上次暂停是yield的返回值 sx.next(url); }) } let sx = sendXml();// 发送请求获取新闻内容 sx.next();
如果觉得文章对你有些许帮助,欢迎在我的GitHub博客点赞和关注,感激不尽!
The text was updated successfully, but these errors were encountered:
```javascript // code
加上javascript,这样代码看着清新些
Sorry, something went wrong.
```javascript // code 加上javascript,这样代码看着清新些
谢谢大佬,关键有时候嫌麻烦
No branches or pull requests
一、迭代器
JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set。这样就需要一种统一的接口机制,来处理所有不同的数据结构。遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
1.Iterator的作用:
2.原生具备iterator接口的数据(可用for of遍历)
3.迭代器的工作原理
4.手写一个迭代器
5.注意点
① for of循环不支持遍历普通对象
对象的Symbol.iterator属性,指向该对象的默认遍历器方法。当使用for of去遍历某一个数据结构的时候,首先去找Symbol.iterator,找到了就去遍历,没有找到的话不能遍历,提示
Uncaught TypeError: XXX is not iterable
② 当使用扩展运算符(...)或者对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法
二、生成器
1.概念
2.特点
Generator 函数是分段执行的,调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回
{value: yield后的表达式结果/undefined, done: false/true}
,再次调用next方法会从上一次停止时的yield处开始,直到最后。第一次调用,Generator 函数开始执行,直到遇到第一个yield表达式为止。next方法返回一个对象,它的value属性就是当前yield表达式的值hello,done属性的值false,表示遍历还没有结束。
第二次调用,Generator 函数从上次yield表达式停下的地方,一直执行到下一个yield表达式。next方法返回的对象的value属性就是当前yield表达式的值world,done属性的值false,表示遍历还没有结束。
第三次调用,Generator 函数从上次yield表达式停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。
第四次调用,此时 Generator 函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true。以后再调用next方法,返回的都是这个值。
3.next传递参数
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
没有传值时result默认是undefined,接下来我们向第二个next传递一个参数,看下输出结果是啥?
4.与 Iterator 接口的关系
我们上文中提到对象没有iterator接口,用for...of遍历时便会报错。
由于 Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。
上面代码中,Generator函数赋值给Symbol.iterator属性,从而使得obj对象具有了 Iterator 接口,可以被for of遍历了。
5.Generator的异步的应用
业务需求:
如何实现(前端核心代码如下):
如果觉得文章对你有些许帮助,欢迎在我的GitHub博客点赞和关注,感激不尽!
参考文章
ECMAScript 6 入门
进阶 Javascript 生成器
ES6生成器函数generator
The text was updated successfully, but these errors were encountered: