为何直接调用squared().next()无法持续迭代,赋值给变量却可行?
问题分析:为何直接调用
squared().next()无法迭代,赋值给变量却可以? 先看你的核心代码逻辑:
function squared() { let n = 0; return { next() { n++; if(n <= 5) { return { value: n * n, done: false }; } return { value: undefined, done: true } } }; }
本质原因:每次调用squared()都会创建全新的作用域与变量
当你直接写
squared().next()时,每一次调用squared()都是一个独立的函数执行过程:- 会重新创建一个局部作用域,初始化
let n = 0; - 返回一个全新的包含
next方法的对象; - 调用这个新对象的
next(),n从0变成1,返回{value:1, done:false}; - 函数执行完毕,这个作用域和里面的
n会被垃圾回收,下次再调用squared()又重复上述步骤,所以永远返回第一个值。
- 会重新创建一个局部作用域,初始化
当你把
squared()的返回值赋值给变量squaredIterator时:- 只调用了一次
squared(),创建了唯一的一个作用域,里面的n被返回的next方法通过闭包持有; squaredIterator保存了这个对象,后续每次调用squaredIterator.next(),都是复用同一个作用域里的n,所以n会持续递增(1→2→3→4→5→6),直到n>5时返回done:true。
- 只调用了一次
不是对象有特殊内存,是闭包在起作用
next方法作为内部函数,会保留对外部函数squared作用域的引用。只要这个next方法所在的对象被变量(比如squaredIterator)持有,squared的作用域就不会被销毁,里面的n值就能被持续保存和修改。
内容的提问来源于stack exchange,提问作者Jamil Samir
相关产品推荐
相关产品推荐

