翰墨写人生 發表於 2025-6-3 16:38:00

Web前端入门第 62 问:JavaScript 循环结构注意事项

<p>HELLO,这里是大熊的前端开发笔记。</p>
<p>循环作为 <code>算法与数据结构</code> 中的基石,JS 与其他编程语言一样,都提供了多种循环结构用于处理数据。</p>
<h3 id="for-循环">for 循环</h3>
<p>事物的开端往往都是从最常用的开始,循环结构咱们从 <code>for</code> 循环说起。</p>
<p>语法:</p>
<pre><code class="language-js">for (初始化; 条件; 增量) {
// ...
}
</code></pre>
<p>示例:</p>
<pre><code class="language-js">// 增量每次 +1
for (let i = 0; i &lt; 10; i++) {
console.log(i);
}
// 增量每次 +2
for (let i = 0; i &lt; 10; i += 2) {
console.log(i);
}
</code></pre>
<p>性能优化:</p>
<p>在使用 for 循环遍历数组的时候,可以提前缓存数组长度,减少 <code>length</code> 的访问次数。</p>
<pre><code class="language-js">const arr = ['前', '端', '路', '引'];
// 提前使用 len 缓存数组长度
for (let i = 0, len = arr.length; i &lt; len; i++) {
console.log(arr);
}
</code></pre>
<p>此示例中使用了 <code>let</code> 同时声明了多个变量,在常规的代码编写中,不建议这么使用,但在循环体这种特殊情况下,这么写也能接受。</p>
<pre><code class="language-js">// 同时声明多个变量
let a = '前端路引', b = 2, c = true;
</code></pre>
<p>增量不一定要使用 <code>i++</code> 自增,也可以使用 <code>i--</code> 递减,或者使用 <code>i += 2</code> 步进,甚至可以是 <code>i += 10</code>。</p>
<h3 id="for-in-循环">for in 循环</h3>
<p>ES6 规范出现之前,只能使用 <code>for in</code> 循环遍历对象,但这哥们有个坑,不止会遍历对象自身属性,还能遍历原型链上可枚举属性。</p>
<pre><code class="language-js">const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
for (let key in obj1) {
console.log(key, obj1);
}
/*
// 输出结果
name 前端路引
age 1
favorite-color red
*/
</code></pre>
<p>看个遍历原型链例子:</p>
<pre><code class="language-js">// 如果有兄弟不小心给对象的原型链上填了一笔
Object.prototype.test = '我是原型链上的测试属性';

const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
for (let key in obj1) {
console.log(key, obj1);
}
/*
// 输出结果
name 前端路引
age 1
favorite-color red
test 我是原型链上的测试属性
*/

for (const key in obj1) {
if (obj.hasOwnProperty(key)) {// 过滤掉原型链属性
    console.log(key, obj1);
}
}
/*
// 输出结果
name 前端路引
age 1
favorite-color red
*/
</code></pre>
<p>如上所示,代码编写规范建议不要对 JS 自身的原型链做修改,扩展原型链虽然方便了一些对象操作,但实际上这是埋了雷的,不知道啥时候就会引爆!!</p>
<p>在使用 <code>for in</code> 循环也需要注意原型链的属性,必须使用 <code>hasOwnProperty</code> 方法来过滤掉原型链上的属性。</p>
<h3 id="for-of-循环">for of 循环</h3>
<p>由于 <code>for in</code> 的各种弊端,后来定规范的大佬们,就新增了一个 <code>for of</code> 循环用于遍历可迭代对象,比如:数组、字符串、Set、Map 等等。</p>
<pre><code class="language-js">const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
// for of 循环
for (let of Object.entries(obj1)) {
console.log(key, value);
}
/* // 以上 let 使用了 解构赋值,其代码等于
for (let item of Object.entries(obj1)) {
const = item;
console.log(key, value);
}
// 又等于
for (let item of Object.entries(obj1)) {
const key = item;
const value = item;
console.log(key, value);
}
*/
</code></pre>
<p><code>for of</code> 无法直接遍历对象,需要遍历对象时,需使用内置方法 <code>Object.entries</code> 将对象转为数组,再使用 <code>for of</code> 遍历,或者使用 <code>Object.keys</code>/<code>Object.values</code> 将对象转为键/值数组再遍历。</p>
<p>相比于 <code>for in</code> 循环,<code>for of</code> 循环性能更好,也不用考虑原型链问题。</p>
<h3 id="while-循环">while 循环</h3>
<p><code>while</code> 循环多用于不确定循环次数的应用场景,比如读取文件数据流,并不知道需要循环多少次才能读取完。</p>
<pre><code class="language-js">let i = 0;

while (i &lt; 3) {
console.log(i);
i++;
}
</code></pre>
<p>一般能用 for 循环的场景,都能使用 while 循环替代。</p>
<h3 id="do-while-循环">do while 循环</h3>
<p>这个循环可有意思了,不管条件是否满足,都会先跑一次循环体,再判断条件。</p>
<p>应用场景例子:必须让用户先输入,再判断条件,直到输入正确才继续。</p>
<pre><code class="language-js">let userInput;
do {
userInput = prompt("请输入一个大于 10 的数字:");
} while (isNaN(userInput) || Number(userInput) &lt;= 10);

console.log("有效输入:", userInput);
</code></pre>
<h2 id="死循环">死循环</h2>
<p>在使用循环遍历时候,需特别注意 <code>死循环</code> 问题,条件处理不好,就进入死循环,导致程序崩溃。</p>
<p>比如:</p>
<pre><code class="language-js">let i = 0;

while (i &lt; 3) {
console.log(i);
// i++; // 忘记修改 i 的值,导致进入死循环
}
</code></pre>
<h2 id="善用退出循环">善用退出循环</h2>
<p><code>continue</code> / <code>break</code> / <code>return</code> 三个关键字都可以用来处理循环逻辑,不同的是:</p>
<ul>
<li><code>continue</code>:跳过当前循环,继续下一次循环。</li>
<li><code>break</code>:跳出当前循环,不再继续循环。</li>
<li><code>return</code>:跳出当前函数,不再继续执行。</li>
</ul>
<p>continue 示例:</p>
<pre><code class="language-js">function loop1 () {
for (let i = 0; i &lt; 10; i++) {
    if (i % 2 === 0) {
      continue; // 跳过偶数次循环,只输出奇数次循环
    }
    console.log(i); // 输出 1 3 5 7 9
}
console.log('循环结束'); // 会执行
}
loop1()
</code></pre>
<p>break 示例:</p>
<pre><code class="language-js">function loop2 () {
for (let i = 0; i &lt; 10; i++) {
    if (i === 5) {
      break; // 在第 6 次循环退出
    }
    console.log(i); // 输出 0 1 2 3 4
}
console.log('循环结束'); // 会执行
}
loop2()
</code></pre>
<p>return 示例:</p>
<pre><code class="language-js">function loop3 () {
for (let i = 0; i &lt; 10; i++) {
    if (i === 5) {
      return; // 在第 6 次循环退出函数,不会执行循环体后面的代码
    }
    console.log(i); // 输出 0 1 2 3 4
}
console.log('循环结束'); // 此行代码不会执行
}
loop3()
</code></pre>
<p>三个退出循环关键字都可以用于所有的循环语句,不要局限于 for 循环~~</p>
<h2 id="写在最后">写在最后</h2>
<p>如果说算法是程序的灵魂,那么循环可以算是算法的基石,很多常见的算法都需要使用循环实现,比如各种数组排序算法、查找算法、最短路径算法等等。</p>
<p>循环是程序中的必修课,任何编程语言都有它的身影。</p>


</div>
<div id="MySignature" role="contentinfo">
    <p>&nbsp;</p>
<p style="font-size: 18px;font-weight: bold;">文章首发于微信公众号【<span style="color:rgb(255, 71, 87)">前端路引</span>】,欢迎 <span style="color:#4ec259">微信扫一扫</span> 查看更多文章。</p>
<p>
<img style="max-width: 320px;" src="https://images.cnblogs.com/cnblogs_com/linx/2447020/o_250228035031_%E5%85%AC%E4%BC%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.png"/>
</p>
<p>本文来自博客园,作者:前端路引,转载请注明原文链接:https://www.cnblogs.com/linx/p/18908725</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/linx/p/18908725
頁: [1]
查看完整版本: Web前端入门第 62 问:JavaScript 循环结构注意事项