JavaScript:生成器的应用

本文探讨了JavaScript中的生成器,重点在于如何利用生成器实现递归以及迭代嵌套的可迭代对象。通过详细的执行过程解释,展示了生成器在处理复杂逻辑时的优势。

生成器的应用


主要参考资料:

  • 《JavaScript 高级程序设计(第4版)》- P199P221(224226/931)

实现递归

使用生成器实现递归:

  • 通过在生成器中迭代该生成器的生成器对象。

示例:

function *generator(n) {
	if(n > 0) {
		yield* generator(n - 1)
		yield n - 1
	}
}

for(const item of generator(3)) {
	console.log(item)
}
// 输出:
// 0
// 1
// 2

示例代码的主要执行过程:

  • 全局作用域 Global
    • 开启作用域 Global-ForOf
      • 执行语句 for-of 迭代生成器对象 generator(3)
    • 暂停作用域 Global-ForOf
      • 开启新的作用域 Global-ForOf-G3
        • 执行生成器中的代码
        • 存储 n = 3
        • 判断 n > 0true
        • 进入语句 if
        • yield* 迭代生成器对象 generator(2)
      • 暂停作用域 Global-ForOf-G3
        • 开启新的作用域 Global-ForOf-G3-G2
          • 执行生成器中的代码
          • 存储 n = 2
          • 判断 n > 0true
          • 进入语句 if
          • yield* 迭代生成器对象 generator(1)
        • 暂停作用域 Global-ForOf-G3-G2
          • 开启新的作用域 Global-ForOf-G3-G2-G1
            • 执行生成器中的代码
            • 存储 n = 1
            • 判断 n > 0true
            • 进入语句 if
            • yield* 迭代生成器对象 generator(0)
          • 暂停作用域 Global-ForOf-G3-G2-G1
            • 开启新的作用域 Global-ForOf-G3-G2-G1-G0
              • 执行生成器中的代码
              • 存储 n = 0
              • 判断 n > 0false
              • 绕过语句 if
              • return 返回 undefined
            • 关闭作用域 Global-ForOf-G3-G2-G1-G0
          • 重启作用域 Global-ForOf-G3-G2-G1
            • yield 返回 n - 1
            • 读取 n = 1 ,返回值 0
          • 暂停作用域 Global-ForOf-G3-G2-G1
    • 重启作用域 Global-ForOf
      • 迭代生成器对象 generator(3) 返回迭代结果 { done: false, value: 0 }
      • 判断 donefalse
      • value 的值 0 赋值给 item
      • 进入语句 for-ofconsole.log(item) 输出 0
      • 再次执行语句 for-of 迭代生成器对象 generator(3)
    • 暂停作用域 Global-ForOf
      • 重启作用域 Global-ForOf-G3-G2-G1
        • return 返回 undefined
      • 关闭作用域 Global-ForOf-G3-G2-G1
      • 重启作用域 Global-ForOf-G3-G2
        • yield 返回 n - 1
        • 读取 n = 2 ,返回值 1
      • 暂停作用域 Global-ForOf-G3-G2
    • 重启作用域 Global-ForOf
      • 迭代生成器对象 generator(3) 返回迭代结果 { done: false, value: 1 }
      • 判断 donefalse
      • value 的值 1 赋值给 item
      • 进入语句 for-ofconsole.log(item) 输出 1
      • 再次执行语句 for-of 迭代生成器对象 generator(3)
    • 暂停作用域 Global-ForOf
      • 重启作用域 Global-ForOf-G3-G2
        • return 返回 undefined
      • 关闭作用域 Global-ForOf-G3-G2
      • 重启作用域 Global-ForOf-G3
        • yield 返回 n - 1
        • 读取 n = 3 ,返回值 2
      • 暂停作用域 Global-ForOf-G3
    • 重启作用域 Global-ForOf
      • 迭代生成器对象 generator(3) 返回迭代结果 { done: false, value: 2 }
      • 判断 donefalse
      • value 的值 2 赋值给 item
      • 进入语句 for-ofconsole.log(item) 输出 2
      • 再次执行语句 for-of 迭代生成器对象 generator(3)
    • 暂停作用域 Global-ForOf
      • 重启作用域 Global-ForOf-G3
        • return 返回 undefined
      • 关闭作用域 Global-ForOf-G3
    • 重启作用域 Global-ForOf
      • 迭代生成器对象 generator(3) 返回迭代结果 { done: true, value: undefined }
      • 判断 donefalse
    • 关闭作用域 Global-ForOf

迭代嵌套可迭代对象的元素

使用生成器迭代嵌套可迭代对象的元素:

  • 在定义可迭代对象类时,将生成器作为可迭代对象的默认迭代器函数。

示例:

// 可迭代对象类
class Iterable {
	constructor() {
		this.values = [1, 2, 3]
	}
	
	// 将生成器作为默认迭代器函数
	*[Symbol.iterator]() {
		yield* this.values
	}
}

// 创建可迭代对象
const iterable = new Iterable()

for(const item of iterable) {
	console.log(item)
}
// 输出:
// 1
// 2
// 3

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值