不错呦!smile@林凯西,确保“准备文件”中的几个文件都有安装,S...您好,看了您这篇帖子觉得很有帮助。但是有个问题想请...我的修改过了怎么还被恶意注册呢 @jjjjiiii 用PJ快9年了,主要是A...PJ3啊,貌似很少有人用PJ了,现在不是WP就是z...@332347365,我当时接入时错误码没有-10...楼主,ChkValue值应为-103是什么意思呢?...大哥 你最近能看到我发的信息,请跟我联系,我有个制...
ES6学习笔记:Iterator接口和Generator函数
编辑:dnawo 日期:2022-04-12
一、Iterator接口
Iterator接口为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署了Iterator,就可以完成遍历操作,举个例子:
customIterator是实现Iterator接口的遍历器生成函数,调用该函数会返回一个遍历器,其内部有一个指针和一个next方法,每一次调用next方法都会移动指针和返回数据结构当前成员的信息,返回值是一个对象,格式为:{value, done},value是当前成员的值,done是一个布尔值,表示遍历是否结束。
对于Array、Map、Set、String、TypedArray、函数的arguments对象、NodeList对象这些数据结构,Javascript原生给它们部署了Iterator,调用这些数据结构的Symbol.iterator属性即可得到遍历器生成函数:
二、Generator函数
Generator函数也是一个遍历器生成函数,它的实现方式和Iterator接口完全不同。Generator函数有两个特征,一是function关键字与函数名之间有一个星号,二是函数体内部使用yield表达式,定义不同的内部状态,每一次调用next方法运行到下一个yield并暂停,返回值和Iterator一样,value为yield表达式的值:
换言之,Generator函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。Generator函数调用时不会立即执行,直到调用next方法才开始执行。利用Generator函数这个特性,我们可以写出任意对象遍历器:
Generator函数也是一个遍历器生成函数,所以将它加到对象的Symbol.iterator属性上面也是可以的:
三、for...of循环
一个数据结构只要部署了Symbol.iterator属性,就被视为具有iterator接口,就可以用for...of循环遍历它的成员:
Iterator接口为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署了Iterator,就可以完成遍历操作,举个例子:
复制内容到剪贴板
程序代码

function customIterator(arr) {
let nextIndex = 0;
return {
next: function() {
if(nextIndex < arr.length){
return {value: arr[nextIndex++], done: false};
}else{
return {value: undefined, done: true};
}
}
};
}
let it = customIterator(['a', 'b']);
it.next(); //{value: 'a', done: false }
it.next(); //{value: 'b', done: false }
it.next(); //{value: undefined, done: true }
let nextIndex = 0;
return {
next: function() {
if(nextIndex < arr.length){
return {value: arr[nextIndex++], done: false};
}else{
return {value: undefined, done: true};
}
}
};
}
let it = customIterator(['a', 'b']);
it.next(); //{value: 'a', done: false }
it.next(); //{value: 'b', done: false }
it.next(); //{value: undefined, done: true }
customIterator是实现Iterator接口的遍历器生成函数,调用该函数会返回一个遍历器,其内部有一个指针和一个next方法,每一次调用next方法都会移动指针和返回数据结构当前成员的信息,返回值是一个对象,格式为:{value, done},value是当前成员的值,done是一个布尔值,表示遍历是否结束。
对于Array、Map、Set、String、TypedArray、函数的arguments对象、NodeList对象这些数据结构,Javascript原生给它们部署了Iterator,调用这些数据结构的Symbol.iterator属性即可得到遍历器生成函数:
复制内容到剪贴板
程序代码

let arr = ['a', 'b'];
let it = arr[Symbol.iterator]();
it.next(); //{value: 'a', done: false }
it.next(); //{value: 'b', done: false }
it.next(); //{value: undefined, done: true }
let it = arr[Symbol.iterator]();
it.next(); //{value: 'a', done: false }
it.next(); //{value: 'b', done: false }
it.next(); //{value: undefined, done: true }
二、Generator函数
Generator函数也是一个遍历器生成函数,它的实现方式和Iterator接口完全不同。Generator函数有两个特征,一是function关键字与函数名之间有一个星号,二是函数体内部使用yield表达式,定义不同的内部状态,每一次调用next方法运行到下一个yield并暂停,返回值和Iterator一样,value为yield表达式的值:
复制内容到剪贴板
程序代码

function* customGenerator() {
yield 'a';
yield 'b';
}
let gt = customGenerator();
gt.next(); //{value: 'a', done: false }
gt.next(); //{value: 'b', done: false }
gt.next(); //{value: undefined, done: true }
yield 'a';
yield 'b';
}
let gt = customGenerator();
gt.next(); //{value: 'a', done: false }
gt.next(); //{value: 'b', done: false }
gt.next(); //{value: undefined, done: true }
换言之,Generator函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。Generator函数调用时不会立即执行,直到调用next方法才开始执行。利用Generator函数这个特性,我们可以写出任意对象遍历器:
复制内容到剪贴板
程序代码

function* customGenerator(obj) {
let propKeys = Reflect.ownKeys(obj);
for (let propKey of propKeys) {
yield [propKey, obj[propKey]];
}
}
let gt = customGenerator({name: 'Jack', age: 30});
gt.next(); //{value: ['name', 'Jack'], done: false }
gt.next(); //{value: ['age', 30], done: false }
gt.next(); //{value: undefined, done: true }
let propKeys = Reflect.ownKeys(obj);
for (let propKey of propKeys) {
yield [propKey, obj[propKey]];
}
}
let gt = customGenerator({name: 'Jack', age: 30});
gt.next(); //{value: ['name', 'Jack'], done: false }
gt.next(); //{value: ['age', 30], done: false }
gt.next(); //{value: undefined, done: true }
Generator函数也是一个遍历器生成函数,所以将它加到对象的Symbol.iterator属性上面也是可以的:
复制内容到剪贴板
程序代码

let person = {
name: 'Jack',
age: 30,
[Symbol.iterator]: function* () {
let propKeys = Object.keys(this);
for (let propKey of propKeys) {
yield [propKey, this[propKey]];
}
}
};
let gt = person[Symbol.iterator]();
gt.next(); //{value: ['name', 'Jack'], done: false }
gt.next(); //{value: ['age', 30], done: false }
gt.next(); //{value: undefined, done: true }
name: 'Jack',
age: 30,
[Symbol.iterator]: function* () {
let propKeys = Object.keys(this);
for (let propKey of propKeys) {
yield [propKey, this[propKey]];
}
}
};
let gt = person[Symbol.iterator]();
gt.next(); //{value: ['name', 'Jack'], done: false }
gt.next(); //{value: ['age', 30], done: false }
gt.next(); //{value: undefined, done: true }
三、for...of循环
一个数据结构只要部署了Symbol.iterator属性,就被视为具有iterator接口,就可以用for...of循环遍历它的成员:
复制内容到剪贴板
程序代码

for(let item of arr){
console.log(item);
}
//a
//b
console.log(item);
}
//a
//b
复制内容到剪贴板
程序代码

for(let item of person){
console.log(item);
}
//['name', 'Jack']
//['age', 30]
console.log(item);
}
//['name', 'Jack']
//['age', 30]
评论: 0 | 引用: 0 | 查看次数: 1763
发表评论
请登录后再发表评论!