概述
迭代器
1.什么是迭代?
迭代就是将一种数据结构按照一定的顺序 不断取出的一个过程叫做迭代
2.迭代和遍历的区别?
迭代强调的是依次取出 不能保证把数据全部取出 也不能确定取出多少
3.什么是迭代器?
迭代器拥有获取下一个数据的能力 在返回的数据中有数据状态 是否继续往下迭代
4.js中规定的迭代器
js中规定 一个对象中 含有next方法 并且这个next方法返回一个对象 那么我们就认为这个对象为迭代器
下面我们就来看看迭代器相关的内容
迭代器(对象)
var obj = {
next() {
// 用于拿到后面的数据
return {
// 就是返回的数据
value : "111",
// 判断是否还有下一个数据
done : false
}
}
}
接下来我们来写一个自定义的迭代器(数组)
let arr = [45, 15, 16, 18];
// 数组的迭代器
const iterator = {
// 声明一个变量让它从0开始迭代
i : 0,
next() {
var result = {
value : arr[this.i],
// 设置迭代状态 (后面还有没有数据)
done : this.i >= arr.length
}
this.i++;
return result;
}
}
console.log(iterator);
// 调用next一次取出对应的状态和值
console.log(iterator.next());
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next());
输出结果为:
每调用一次就会依次取出一个值,在这里大家可以发现return这是运用了闭包的原理。
接下来我们来试着封装一下自定义数组的迭代器
function createIterator(arr) {
// 声明一个变量让它从0开始迭代
let i = 0;
return {
next() {
var result = {
value: arr[i],
// 设置迭代状态 (后面还有没有数据)
done: i >= arr.length
}
i++;
return result;
}
}
}
var arr1 = [15, 18, 13, 17];
var iter = createIterator(arr1);
console.log(iter.next().value);//15
console.log(iter.next().value);//18
console.log(iter.next().value);//13
console.log(iter.next().value);//17
console.log(iter.next().value);//undefined
接着我们来封装个经典的斐波拉契
斐波拉契是 0,1,1,2,3,5…
即后面一个数为前两个数的和:
function createFeiboIter() {
// 定义数组初始值
let pre1 = 1;
let pre2 = 1;
// 记录当前位置
let n = 1;
return {
next() {
let value;
if (n <= 2) {
value = 1;
} else {
value = pre1 + pre2;
}
var res = {
value,
done: false // 不管它的结束值 只管next方法
}
// 换掉初始值
pre1 = pre2;
pre2 = res.value;
n++;
return res;
}
}
}
var iterator = createFeiboIter();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
console.log(iterator.next().value); // 5
我们来看看数组的迭代器
// 在ES6里面 如果对象具有知名符号Symbol.iterator这个属性 那么就说明这个对象可以进行迭代
let iter = arr[Symbol.iterator]();
对象设置迭代器
var obj = {
a : 12,
b : 15,
c : 19,
[Symbol.iterator] () {
// 拿到对象所有的键名
const keys = Object.keys(this);
let i = 0
// 设置迭代器
return {
next : () => {
const propName = keys[i];
const propValue = this[propName];
var result = {
value : {
propName,
propValue
},
done : i++ >= keys.length
}
return result;
}
}
}
}
for(const item of obj) {
console.log(item);
}
结果为:
生成器(generator)
什么是generator函数?
是一种ES6里面提供的一种方法 他是yield标识符和next方法调用 作用是可以是函数分段调用
怎么使用生成器?
function* love() {
yield "1";
yield "2";
yield "3";
return "over"
}
var loves = love();
console.log(loves.next());
console.log(loves.next());
console.log(loves.next());
console.log(loves.next());
console.log(loves.next());
输出为:
调用next方法之后的逻辑 :
1.当函数调用next方法之后 在函数内部遇到了yield关键字 函数就会暂停执行 next方法的返回值就是yeild 后面接的数据
2.当我们再次调用next方法时 就会从当前暂停的位置继续往下走 直到遇到下一个yield
3.运行到最后 没有yield关键字 就会一直往后执行 直到遇到return 关键字 返回的是return后面的值 并且状态变成true
4.最后没有遇到return 返回值为undefined 状态值为true
generator函数的特性 :
1.generator函数是分步执行的 以yield 为标志 表示函数暂停执行 通过调用next方法恢复函数执行
2.generator函数的写法跟普通函数有区别 在function关键字和函数名之前加一个* 通常情况下 *紧挨着function写
3.generator函数直接调用 是不会执行函数体的 而是要调用next方法 才能往下执行
4.generator函数调用之后 返回的值是一个iterator对象 只有调用next方法 才会迭代 进入下一个状态
生成器 : 生成器指的是 通过构造函数Generator创建出的生成器对象 让函数可以分布执行 生成器也是一个迭代器 同时也是一个可以迭代的对象
Async和 * 不能同时使用
下面我们来看看数组的生成器
var arr = [15, 16, 17, 19];
function* createGenerator(arr) {
for(const item of arr) {
yield item;
}
}
const iter = createGenerator(arr);
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
结果为:
下面我们在看看生成器里面调用另外一个生成器
function* f1() {
yield 1;
yield 2;
}
function* f2() {
yield* f1(); // 在生成器内部调用其他的生成器 一定要在yield 后面加上*
yield 4;
// return 方法调用之后 就会提前结束生成器函数 整个迭代过程提前结束
// return 9;
// 可以在生成器内部抛出一个错误
// throw 8;
yield 5;
yield 6;
}
const gener = f2();
console.log(gener.next());
console.log(gener.next());
console.log(gener.next());
console.log(gener.next());
console.log(gener.next());
console.log(gener.next());
结果为:
以上就是迭代器和生成器的相关内容了,如果觉得有帮助的话记得点赞加关注哦
最后
以上就是清脆外套为你收集整理的ES6中的迭代器和生成器迭代器生成器(generator)的全部内容,希望文章能够帮你解决ES6中的迭代器和生成器迭代器生成器(generator)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复