关于前端循环的几种方式

循环数组或类数组对象

使用 for 循环是最基础的方式,适用于数组或类数组对象。通过索引访问元素,可以灵活控制循环的起始和结束位置。

const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) { // arr.length表示数组的长度

  console.log(arr[i],i);  // i表示数字 arr[i]表示当前标识中的值 如arr[0]=1
}

打印结果如下:

前面为展示打印值,后面为打印i的值。数组中的起始一般是从0,若是i=1,则是从数组中第二位开始循环。i一般用于表示循环的次数,从哪里开始循环。

遍历对象属性

for...in 循环用于遍历对象的可枚举属性,包括原型链上的属性。通常需要配合 hasOwnProperty 检查属性是否属于对象自身。

const obj = { a: 1, b: 2 };
for (const key in obj) {
  if (obj.hasOwnProperty(key)) { // key表示a/b
    console.log(key, obj[key]);
  }
}

执行结果如下:

遍历数组元素

for...of 循环直接遍历可迭代对象(如数组、字符串、Map、Set)的值,无需处理索引。语法简洁,适合需要直接操作元素的场景。

const arr = [1, 2, 3];
for (const item of arr) {
  console.log(item);
}

打印结果如下:

数组高阶函数:map

Array.prototype.map 对数组每个元素执行回调函数,返回新数组。适合需要基于原数组生成新数组的场景,且不改变原数组。

const arr = [1, 2, 3];
const newArr = arr.map(item => item * 2);
console.log(newArr,arr); // [2, 4, 6]  [1,2,3]

打印结果如下:

数组高阶函数:forEach

Array.prototype.forEach 遍历数组每个元素并执行回调函数,无返回值。适合仅需遍历执行操作的场景,不能中断循环。

const arr = [1, 2, 3];
arr.forEach(item => {
  console.log(item);
});

打印结果如下:

数组高阶函数:filter

Array.prototype.filter 返回满足条件的元素组成的新数组。适合需要筛选特定元素的场景。不会改变原数组的值。

const arr = [1, 2, 3];
const filtered = arr.filter(item => item > 1);
console.log(filtered,arr); // [2, 3]  [1,2,3]

打印结果如下:

数组高阶函数:reduce

Array.prototype.reduce 通过累加器处理数组元素,返回单个值。适合需要汇总或计算的场景,如求和、扁平化数组等。

const arr = [1, 2, 3];
const sum = arr.reduce((acc, item) => acc + item, 0);
console.log(sum); // 6

打印结果如下图:

While 循环

while 循环在条件为真时重复执行代码块。适合不确定循环次数的场景,需注意避免无限循环。

let i = 0;
while (i < 3) {
  console.log(i);
  i++; // i已经在这里进行了累加
  console.log('累加后的i=',i)  // 这里打印就是累加后的i
}

执行结果如下:

注:若是区分不清楚,可以在打印时加文字进行区分。

Do...While 循环

do...while 循环至少执行一次代码块,之后检查条件。适合需要至少执行一次的场景。


do {  
  // 循环体代码
} while (条件表达式); // 条件:当此条件为真时,循环体会继续执行


/*以下为条件为真时的处理结果*/
let i = 0;
do {
  console.log(i);
  i++;
} while (i < 3);



/*以下为条件不为真时的处理结果*/
let i = 0;
do {
  console.log(i);
  i++;
} while (i >3);

当条件不满足时,进入循环之后的打印结果:

初始值进入循环后,即使i累加后,条件依旧不满足,这时就会直接跳出循环进行。

当条件满足时进入循环后的结果:

前端开发中,深拷贝是指将一个对象从内存中完全复制一份,使得新对象与原对象之间互不影响。与浅拷贝不同,深拷贝不仅复制对象的顶层属性,还会递归复制对象中的嵌套引用类型。以下是几种常见的实现深拷贝的方法: ### 1. 使用 `JSON.parse(JSON.stringify())` 这是实现深拷贝最简单的方式之一,适用于对象中不包含函数、`undefined`、`Symbol`等特殊类型的情况。 ```javascript const original = { a: 1, b: { c: 2 } }; const deepCopy = JSON.parse(JSON.stringify(original)); ``` 该方法的局限性在于无法复制函数、`undefined`、`Symbol`等类型,并且会丢失对象中的循环引用[^5]。 --- ### 2. 递归实现深拷贝 递归方法是深拷贝的核心实现原理,尤其适用于多层级嵌套对象或数组的情况。通过遍历对象的每个属性并递归复制,确保每个层级都生成新的对象。 ```javascript const deepCopy = (obj) => { if (obj === null || typeof obj !== 'object') return obj; const result = Array.isArray(obj) ? [] : {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { result[key] = deepCopy(obj[key]); } } return result; }; ``` 该方法可以处理嵌套对象,但未处理循环引用问题[^2]。 --- ### 3. 利用第三方库实现深拷贝 一些流行的前端库(如 Lodash)提供了深拷贝的实现方法,例如 `_.cloneDeep()`,可以有效处理复杂的数据结构,包括循环引用。 ```javascript const _ = require('lodash'); const original = { a: 1, b: { c: 2 } }; const deepCopy = _.cloneDeep(original); ``` 这种方式功能强大且经过优化,适用于复杂的深拷贝需求[^3]。 --- ### 4. 使用浏览器原生 API(如 `structuredClone`) 现代浏览器支持 `structuredClone` 方法,它可以在不丢失循环引用的情况下实现深拷贝。 ```javascript const original = { a: 1, b: { c: 2 } }; const deepCopy = structuredClone(original); ``` 该方法比 `JSON.parse(JSON.stringify())` 更强大,支持更多数据类型,但兼容性可能受限[^5]。 --- ### 5. 手动实现深拷贝并处理循环引用 为了处理对象中可能存在的循环引用,可以在递归的基础上引入一个 `Map` 来记录已复制的对象。 ```javascript const deepCopy = (obj, visited = new Map()) => { if (obj === null || typeof obj !== 'object') return obj; if (visited.has(obj)) return visited.get(obj); const result = Array.isArray(obj) ? [] : {}; visited.set(obj, result); for (const key in obj) { if (obj.hasOwnProperty(key)) { result[key] = deepCopy(obj[key], visited); } } return result; }; ``` 该方法能够有效避免循环引用导致的栈溢出问题,适用于更复杂的场景。 --- ### 6. 使用 `jQuery.extend()`(传统方式) 在使用 jQuery 的项目中,可以通过 `$.extend(true, {}, original)` 实现深拷贝。 ```javascript const original = { a: 1, b: { c: 2 } }; const deepCopy = $.extend(true, {}, original); ``` 虽然 jQuery 的深拷贝方法功能完善,但在现代项目中使用较少,主要适用于遗留项目[^3]。 --- ### 总结 不同的深拷贝方法适用于不同的场景。如果对象结构简单且不需要处理循环引用,`JSON.parse(JSON.stringify())` 是最简单的方式。对于复杂对象,递归实现或使用第三方库(如 Lodash)是更可靠的选择。现代浏览器支持的 `structuredClone` 方法提供了更强大的深拷贝能力,适用于需要兼容多种数据类型的场景。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值