js 迭代器next和生成器yield的区别
<p><strong>迭代器(Iterator)</strong>和<strong>生成器(Generator)</strong>是 JavaScript 中用于处理遍历和惰性求值的两个重要概念。它们密切相关,但有明显的区别。以下是它们的核心区别和联系:</p><hr>
<h3 id="1-迭代器iterator">1. <strong>迭代器(Iterator)</strong></h3>
<ul>
<li><strong>定义</strong>:迭代器是一个对象,它实现了迭代器协议,即具有 <code>next()</code> 方法。</li>
<li><strong><code>next()</code> 方法</strong>:每次调用 <code>next()</code> 方法,返回一个包含 <code>value</code> 和 <code>done</code> 属性的对象。
<ul>
<li><code>value</code>:当前迭代的值。</li>
<li><code>done</code>:布尔值,表示迭代是否完成。</li>
</ul>
</li>
<li><strong>手动实现</strong>:需要显式定义 <code>next()</code> 方法。</li>
<li><strong>用途</strong>:用于遍历数据集合。</li>
</ul>
<h4 id="示例自定义迭代器">示例:自定义迭代器</h4>
<pre><code class="language-javascript">const myIterator = {
data: ,
index: 0,
next() {
if (this.index < this.data.length) {
return { value: this.data, done: false };
} else {
return { value: undefined, done: true };
}
},
};
console.log(myIterator.next()); // { value: 1, done: false }
console.log(myIterator.next()); // { value: 2, done: false }
console.log(myIterator.next()); // { value: 3, done: false }
console.log(myIterator.next()); // { value: undefined, done: true }
</code></pre>
<hr>
<h3 id="2-生成器generator">2. <strong>生成器(Generator)</strong></h3>
<ul>
<li><strong>定义</strong>:生成器是一种特殊的函数,使用 <code>function*</code> 定义,通过 <code>yield</code> 关键字暂停和恢复执行。</li>
<li><strong>返回值</strong>:生成器函数调用后返回一个生成器对象,该对象实现了迭代器协议(即具有 <code>next()</code> 方法)。</li>
<li><strong>自动实现</strong>:生成器函数自动生成迭代器,无需手动实现 <code>next()</code> 方法。</li>
<li><strong>用途</strong>:用于简化迭代器的创建,支持惰性求值。</li>
</ul>
<h4 id="示例生成器函数">示例:生成器函数</h4>
<pre><code class="language-javascript">function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
const iterator = myGenerator();
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 }
</code></pre>
<hr>
<h3 id="3-核心区别">3. <strong>核心区别</strong></h3>
<table>
<thead>
<tr>
<th><strong>特性</strong></th>
<th><strong>迭代器(Iterator)</strong></th>
<th><strong>生成器(Generator)</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>定义方式</strong></td>
<td>手动实现 <code>next()</code> 方法的对象。</td>
<td>使用 <code>function*</code> 定义的函数。</td>
</tr>
<tr>
<td><strong>实现复杂度</strong></td>
<td>需要手动管理状态(如索引)。</td>
<td>自动管理状态,通过 <code>yield</code> 暂停和恢复执行。</td>
</tr>
<tr>
<td><strong>返回值</strong></td>
<td>直接是迭代器对象。</td>
<td>返回生成器对象,生成器对象是迭代器。</td>
</tr>
<tr>
<td><strong>适用场景</strong></td>
<td>需要完全控制迭代逻辑时使用。</td>
<td>简化迭代器创建,支持惰性求值。</td>
</tr>
<tr>
<td><strong>语法支持</strong></td>
<td>无特殊语法,需手动实现。</td>
<td>使用 <code>function*</code> 和 <code>yield</code> 语法。</td>
</tr>
</tbody>
</table>
<hr>
<h3 id="4-联系">4. <strong>联系</strong></h3>
<ul>
<li><strong>生成器是迭代器的语法糖</strong>:生成器函数返回的生成器对象实现了迭代器协议,因此生成器是一种特殊的迭代器。</li>
<li><strong>生成器简化了迭代器的创建</strong>:通过生成器,开发者无需手动实现 <code>next()</code> 方法,只需使用 <code>yield</code> 关键字即可。</li>
</ul>
<hr>
<h3 id="5-示例对比">5. <strong>示例对比</strong></h3>
<h4 id="使用迭代器遍历数组">使用迭代器遍历数组</h4>
<pre><code class="language-javascript">const myIterator = {
data: ,
index: 0,
next() {
if (this.index < this.data.length) {
return { value: this.data, done: false };
} else {
return { value: undefined, done: true };
}
},
};
let result = myIterator.next();
while (!result.done) {
console.log(result.value); // 1, 2, 3
result = myIterator.next();
}
</code></pre>
<h4 id="使用生成器遍历数组">使用生成器遍历数组</h4>
<pre><code class="language-javascript">function* myGenerator() {
const data = ;
for (const item of data) {
yield item;
}
}
const iterator = myGenerator();
let result = iterator.next();
while (!result.done) {
console.log(result.value); // 1, 2, 3
result = iterator.next();
}
</code></pre>
<hr>
<h3 id="6-总结">6. <strong>总结</strong></h3>
<ul>
<li><strong>迭代器</strong>:是一个实现了 <code>next()</code> 方法的对象,用于手动控制遍历逻辑。</li>
<li><strong>生成器</strong>:是一种特殊的函数,通过 <code>function*</code> 和 <code>yield</code> 自动生成迭代器,简化了遍历逻辑。</li>
<li><strong>生成器是迭代器的语法糖</strong>:生成器返回的对象实现了迭代器协议。</li>
<li><strong>选择使用</strong>:
<ul>
<li>如果需要完全控制遍历逻辑,使用迭代器。</li>
<li>如果需要简化代码并支持惰性求值,使用生成器。</li>
</ul>
</li>
</ul>
<p>理解迭代器和生成器的区别与联系,可以帮助你更好地处理遍历和惰性求值的场景。</p>
</div>
<div id="MySignature" role="contentinfo">
前端工程师、程序员<br><br>
来源:https://www.cnblogs.com/jocongmin/p/18691234
頁:
[1]