首页 > 编程语言 >javascript 高级编程系列 - 迭代器/生成器

javascript 高级编程系列 - 迭代器/生成器

时间:2023-02-17 17:57:16浏览次数:37  
标签:console log 迭代 javascript 生成器 value let iterator

1. 迭代器(Iterator)

  • 特殊对象,具有迭代过程的接口next()方法
  • 每次调用next()方法,返回一个结果对象
  • 结果对象有两个属性value(任何类型)和done(布尔类型)
  • 当集合的值返回完时,再次调用next()方法,结果对象的done属性值为true,value为迭代器最终返回的值。

使用javascript创建迭代器

function createIterator(items){
  let i = 0;
  return {
    next: () => {
      let done = (i >= items.length);
      let value = !done ? items[i++] : undefined;
      return { done, value };
    }
  };
}

const iterator = createIterator([1,2,3]);
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

2. 生成器(Generator)

  • 生成器是一种返回迭代器的函数, 通过function关键字后面的*来表示
  • 函数中会用到yield关键字,并且只能在生成器内部使用,在嵌套函数中也不允许使用
  • 每执行完一条yield语句后,函数就会自动停止执行,直到再次调用迭代器的next()方法
  • 不能使用箭头函数来创建生成器

创建生成器

function *createIterator() {
  yield 1;
  yield 2;
  yield 3;
}
const iterator = createIterator();
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

创建生成器函数表达式

const createIterator = function *(items){
  for (let i = 0; i < items.length; i++){
    yield items[i];
  }
}
const iterator = createIterator([1,2,3]);
for (let value of iterator){
  console.log(value);
}
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

3. 可迭代对象与for-of循环

  • 可迭代对象具有Symbol.iterator属性,是一种与迭代器密切相关的对象。
  • Symbol.iterator属性通过指定的函数可以返回一个作用与附属对象的迭代器。
  • 所有集合对象(数组,Set集合,Map集合)以及字符串都是可迭代对象。
  • for-of 循环每执行一次就会调用可迭代对象的next()方法,并将迭代器返回的结果对象的value属性存储在
    一个变量中,循环持续这一过程,直到结果对象的done属性值为true
  • 生成器默认会为Symbol.iterator属性赋值,通过生成器创建的迭代器都是可迭代对象

生成器产生的迭代器是可迭代对象

const createIterator = function *(items){
  for (let i = 0; i < items.length; i++){
    yield items[i];
  }
}
const iterator = createIterator([1,2,3]);
for (let value of iterator){
  console.log(value); // 1, 2, 3
}

4. 访问默认迭代器

  • 可以通过Symbol.iterator来访问对象默认的迭代器
const values = [1, 2, 3];
const iterator = values[Symbol.iterator]();
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
  • 检测对象是否为可迭代对象
function isIterable(object){
  return typeof object[Symbol.iterator] === 'function';
}
const setObj = new Set([1,2,3]);
console.log(isIterable(setObj)); // true

5. 创建可迭代对象

  • 通过给普通对象Symbol.iterator属性添加一个生成器,从而使其变为可迭代对象
const collection = {
  items: [1,2,3],
  *[Symbol.iterator]() {
    for (let item of this.items){
      yield item;
    }
  }
};

for (let item of collection){
  console.log(item); // 1, 2, 3
}

6. 内建迭代器

ES6中有3种类型的集合对象:数组,Map集合,Set集合,它们都内建了以下三种迭代器:

  • keys() 返回一个迭代器,其值为集合中所有的键名

  • values() 返回一个迭代器,其值为集合的值

  • entries() 返回一个迭代器,其值为多个键值对

  • 数组(默认迭代器为values())

let colors = ['red', 'green', 'blue'];

for (let entry of colors.entries()){
  console.log(entry); // [0, 'red'] [1, 'green'] [2, 'blue']
}
for (let key of colors.keys()){
  console.log(key); // 0, 1, 2
}
for (let value of colors.values()) {
  console.log(value); // 'red', 'green', 'blue'
}
// 使用默认迭代器
for( let color of colors){
  console.log(color); // 'red', 'green', 'blue'
}
  • Set集合(默认迭代器为values())
let numbers = new Set([1, 2, 3]);
for (let entry of numbers.entries()){
  console.log(entry); // [1, 1] [2, 2] [3, 3]
}
for (let key of numbers.keys()){
  console.log(key); //  1, 2, 3
}
for (let value of numbers.values()) {
  console.log(value); //1, 2, 3
}
// 使用默认迭代器
for (let number of numbers){
  console.log(number); // 1, 2, 3
}
  • Map集合(默认迭代器为entries())
let data = new Map([['name', 'mike'], ['age', '30']]);
for (let entry of data.entries()){
  console.log(entry); // ['name', 'mike'] ['age', '30']
}
for (let key of data.keys()){
  console.log(key); //  'name', 'age'
}
for (let value of data.values()) {
  console.log(value); // 'mike', '30'
}
// 使用默认迭代器
for (let [key, value] of data){
  console.log(key); // 'name', 'age'
  console.log(value); // 'mike', '30'
}
  • 字符串迭代器
const message = 'ab你好cd';
for (let c of message){
  console.log(c); // 'a', 'b', '你', '好', 'c', 'd'
}

标签:console,log,迭代,javascript,生成器,value,let,iterator
From: https://www.cnblogs.com/xiaodi-js/p/17131049.html

相关文章

  • JavaScript常见问题梳理
    1、this指向1、全局函数this指向全局对象window,注意严格模式下,this为undefined//[objectWindow]alert(this);functionf(){alert(this)}f()//undefinedfu......
  • javascript的一些基础知识
    随手记录一些javascript的一些基础知识,之前只是简单用到javascript,并没有了解其中的概念。1. JavascriptObject:InJavaScript,almost"everything"isanobject.......
  • [javascript]端序(endian)和Buffer对象的read|write系列函数
    假设有如下对象:varbuf=Buffer.from("Hello.\n");其保存在内存当中的形式实际上是这样的,这里我们假设该对象的内存地址从0x00开始:地址0x000x010x020x030x04......
  • 2023前端开发最新面试题收集-Javascript篇
    前台、中台、后台-前台:面向用户、客户可以感知的,如商城-中台:可以看着对前台的补充,公共服务功能,如支付系统、搜索系统、客服-后台:面向运营、比如商品管理、物流管理1......
  • 78JavaScript基础
    JavaScript操作DOM节点包括:JavaScript处理事件、操作节点、操作节点样式#demo.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><me......
  • javascript 高级编程系列 - async/await
    async/await其实是生成器的语法糖,async用于声明一个函数是异步的,而await用于等待一个异步方法执行完成,并且await只能出现在async函数中。1.async函数async函数返回一......
  • JavaScript 基础 - Day01
    了解变量、数据类型、运算符等基础概念,能够实现数据类型的转换,结合四则运算体会如何编程。体会现实世界中的事物与计算机的关系理解什么是数据并知道数据的分类理解......
  • 【Python】字母表的循环迭代
     字母循环迭代器defforward(letter,jump):"""字母表上的循环迭代器"""ifletter.islower():start_character=ord('a')......
  • JavaScript体验
    JavaScript体验(来自本站javascript教程)JavaScript实例代码:JavaScript可以直接在HTML输出:document.write("<p>这是一个段落。</p>");JavaScript事件响应:<bu......
  • 代码随想录算法Day14 | 理论基础,递归遍历,迭代遍历,统一迭代
    理论基础1、二叉树的种类满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。    这棵二叉树为满二叉树,也......