for、while、do While、for in、forEach、map、reduce、every、some、filter的使用

for、while、do While、for in、forEach、map、reduce、every、some、filter的使用

for

let arr = [2, 4, 6, 56, 7, 88];//for
for (let i = 0; i < arr.length; i++) {console.log(i + ':' + arr[i]) //0:2 1:4 2:6 3:56 4:7 5:88
}

普通的for循环可以用数组的索引来访问或者修改原来数组对应的元素,即可以改原数组的数据

while

//while
let arr=[1,0,8,7],i=0;
while(i<arr.length){console.log(i+':'+arr[i]);//0:1 1:0 2:8 3:7i++;
}

do while

//do while
let arr=[1,0,8,7],i=0;
do{console.log(i+':'+arr[i]);//0:1 1:0 2:8 3:7i++
}while(i<arr.length)

for in

let obj = {name: '小明',age: 18,hobby: 'run,song,game'
};for(let key in obj){console.log(key+':'+obj[key]) //name:小明 age:18 hobby:run,song,game
}

注意,对象也可以遍历的。

for of

let arr = [2, 4, 6, 56, 7, 88];
let obj = {name: '小明',age: 18,hobby: 'run,song,game'
};
for(let value of arr){console.log(value) //2 4 6 56 7 88
}for (let [key, value] of arr.entries()) {console.log(key+':'+value); //0:2 1:4 2:6 3:56 4:7 5:88
}for (let [key, value] of Object.entries(obj)) {console.log(key+':'+value); //name:小明 age:18 hobby:run,song,game
}

注意:这个for of既可以遍历列表也可以遍历对象。

forEach

最节省内存的一种遍历方式,但是不能用break,也不能用return

let arr = [2, 4, 6, 56, 7, 88];
let obj = {name: '小明',age: 18,hobby: 'run,song,game'
};
arr.forEach((value,key)=>{console.log(key + ':' + value) //0:2 1:4 2:6 3:56 4:7 5:88
})Object.keys(obj).forEach((value)=>{console.log(value) //"name", "age", "hobby"
})

既可以遍历列表也可以遍历对象。

注意:forEach会改变原来数组中的值。

let arr = [{ id: '01001', title: '考研成绩' },{ id: '01002', title: '中国经济复苏进度条' },
]
arr.forEach(function(item,index,arr){item.date = "2023-1-1"
})console.log(arr)

image-20231022181249203

我们改变了原数组,并且,从上面例子可以看出,在js中,可以给一个对象直接添加一个原来没有的属性。

map

同forEach写法一样,循环每一个的时候就相当于在内存中新建了一个数据,比较占内存,与forEach不同的是,它可以return。返回数组。

let arr = [2, 4, 6, 56, 7, 88];
let obj = {name: '小明',age: 18,hobby: 'run,song,game'
};
arr.map((value,index)=>{console.log(index+':'+value) //0:2 1:4 2:6 3:56 4:7 5:88
})Object.values(obj).map((value,key)=>{console.log(key+':'+value) //0:小明 1:18 2:run,song,game
})console.log(Object.keys(obj)) // (3) ["name", "age", "hobby"]
console.log(Object.values(obj)) // (3) ["小明", 18, "run,song,game"]

image-20231022175250501

注意:map方法不会改变原来数组

let arr = [1,2,3,4,5]
let newArr = arr.map(function(item,index,arr){return item*2
})
console.log(arr) // [1,2,3,4,5]
console.log(newArr) // [2,4,6,8,10]

image-20231022181545870

但是对于数组中引用类型中的属性修改,还是会影响原来的数组中对象的属性值的。效果就和forEach一样了。

let arr = [{ id: '01001', title: '考研成绩' },{ id: '01002', title: '中国经济复苏进度条' },
]let newArr = arr.map(function(item,index,arr){item.date = "2023-1-1"return item
})
console.log("arr",arr)
console.log("newArr",newArr)

image-20231022181829867

但是可以用{…item}来做拷贝,然后我们修改拷贝后的值就行了,这样就不会影响原来的数组数据了。

let arr = [{ id: '01001', title: '考研成绩' },{ id: '01002', title: '中国经济复苏进度条' },
]let newArr = arr.map(function(item,index,arr){item = {...item} // 这里我们多了一步拷贝处理item.date = "2023-1-1"return item
})console.log("arr",arr)
console.log("newArr",newArr)

image-20231022182044476

扩展:

js中…的用法

1.什么是…

…是扩展运算符,是es6的新语法

2.怎么使用

作用在对象上,返回一个对象,取出对象所有可遍历属性,返回一个新的对象可以进行拷贝

  1. 基本用法

    let person = { name:'张三',age:18}let someone = {...person}console.log(someone) //返回 { name:'张三',age:18 }
    
  2. 作用于数组对象

    et array = ['a','b','c']let obj = {...array} console.log(obj) // {0:'a',1:'b',2:'c'} 说明:给数组的每个元素生成key,从0开始返回一个新的对象
    
  3. 合并对象

    let name = { name:'张三' }let age = { age:18 }let person = { ...name,...age }console.log(person)  //{name:'张三',age:18}
    
  4. 属性的合并

    let person = {name: "Amy", age: 15};let someone = { ...person, name: "Mike", age: 17};console.log(someone); //{name: "Mike", age: 17} 说明:自定义属性和扩展属性相同的时候,将会被覆盖。如果自定义属性在前,那么扩展属性覆盖自定义属性。反之则是自定义属性覆盖拓展属性。
    

filter

作用:不影响原数组,这个方法会返回一个新数组。回调函数若返回true,filter就会把这一项添加到要返回的新数组中作为一个元素。

注意:传入的函数里必填return,因为会根据return的值为false或true来过滤数据。

filter的几种情况如下:

(1)直接return布尔值,为true则元素值放入数组中,为false的就被过滤掉。

例子1:

let arr = [{ id: '01001', title: '考研成绩', isHot: true },{ id: '01002', title: '中国经济复苏进度条', isHot: false },
]let result = arr.filter((item) => {return item.isHot
})console.log(result) // [{ id: '01001', title: '考研成绩', isHot: true }]// 看打印结果可以发现isHot为false的对象数据就被过滤掉了

例子2:

let arr = [1,2,3,4,5];
let result = arr.filter(function(item, index) {return item>2;
});
console.log(result);
// 输出[ 3, 4, 5 ]
// item:当前元素  index:当前元素的索引值

(2)return非布尔值时,也会通过将数据隐式转化为布尔值来过滤数组。

例子:

let arr = [1,undefined,null,3,0,"",NaN]
let result = arr.filter((item) => {return item
})console.log(result) // [1,3]// 将item的值转化为布尔值后,为false的元素就被过滤掉了,留下的为true的

(3)与其他方法结合使用:

这里先用一个小例子帮大家回忆一下数组的indexOf()方法的用法:用于返回某个指定的值在数组中首次出现的索引值,如果没有找到匹配的元素则返回 -1。

let arr = [1, 2, 3, 4, 5];
let index = arr.indexOf(2);
// 在数组中查找是否有2这个元素
console.log(index) //打印结果是1,表示2和数组中索引为1的元素的值匹配

①与indexOf()方法组合使用进行数组去重:

let arr = [1,1,2,4,5,6,5,5,6]
let newArr = arr.filter((item,index)=>{return arr.indexOf(item) === index// 因为indexOf始终返回第一个符合条件的元素的索引// 数组中重复出现的数值就不可能满足全等判断,就会被过滤掉
})console.log(newArr) // [1,2,4,5,6]

②还有与map方法一起使用:

let arr = [{ id: '01001', title: '考研成绩', isHot: true },{ id: '01002', title: '中国经济复苏进度条', isHot: false },
]// 用map方法给数据加上日期属性let result = arr.map((item) => {item = {...item}item.date = '2023-01-01'return item// map方法后紧接着使用filter方法过滤数据
}).filter((item) => {return item.isHot === true
})console.log(result)

reduce

作用:遍历数组,并构建返回一个最终的值。

语法:array.reduce(function(previous,current,index,arr),initValue);

参数说明:

①不传第二参数initValue时,我们以一个计算数组元素相加之和的例子说明:

let arr = [1,3,5,7]
let result = arr.reduce((previous,current)=>{console.log('previous:',previous, ' current:',current)return previous + current
})console.log('result:',result)

打印结果为:

image-20231022184654345

我们可以看到:

  • 传入的箭头函数执行了数组长度-1次,也就是3次;

  • 回调函数多次调用:

    第一次调用时,previous表示就是数组的第一个元素的值1,current是数组第二个元素的值3;

    第二次调用时,previous表示的是上次调用时return出来的值也就是1+3为4,current是数组第三个元素的值5;

    第三次调用时,previous同样表示的是上次调用返回的值也就是4+5为9,current表示数组第四个元素的值7。

  • result的值就是最后一次计算9+7的结果值16。

②传入第二参数initValue时,我们以一个获得新数组的每个元素是原数组每个元素累计相加之和的例子说明:

let arr = [1,3,5,7]
let sum = 0
let result = arr.reduce((previous,current)=>{console.log(previous, 'current:', current)previous.push(sum + current)sum += currentreturn previous
}, [])console.log('result:', result)

打印结果为:

image-20231022185146784

我们可以看到:

  • 传入的箭头函数执行了arr数组长度一样的次数,也就是4次;
  • previous:箭头函数第一次调用时,表示的是传入的初始值initValue,也就是空数组,后面表示的是上次return出来的值;current:始终表示的是数组arr的每个元素的值;
  • result同样表示最后一次箭头函数调用return返回的结果。

reduce的使用例子:

上面我们举了2个简单例子区分reduce方法传入1个参数和2个参数的区别,下面我以一个计算购物车选中产品数量的例子来说明项目中reduce的具体应用场景。

image-20231022185321361

目前购物车一共有3个产品,其中选中了2种产品,并计算选中的总价为22393,我们可以通过reduce方法计算①②这个2个值。

// arr表示购物车里所有产品数组,其中用不到的数据就省略了
let arr = [{id:12334,isChecked:1, // 1表示购物车选中了这个产品cartPrice:5999, // 表示产品单价5999skuNum:1, // 表示购物车产品数量为1skuName:"小米10 至尊纪念版 双模5G 骁龙865 120W快充 8GB+128GB 陶瓷黑 游戏手机",},{id:12375,isChecked:0, // 0表示购物车没有选中这个产品cartPrice:2323, // 表示产品单价为2323skuNum:1, // 表示购物车产品数量为1skuName:"华为P40 5G全网通智能手机 支持鸿蒙HarmonyOS 零度白 8G+128G",},{id:12376,isChecked:1, // 1表示购物车选中了这个产品cartPrice:8197, // 表示产品单价为8197skuNum:1, // 表示购物车产品数量为1skuName:"Apple iPhone 12 (A2404) 64GB 黑色 支持移动联通电信5G 双卡双待手机",}
]

因为每个产品对象的isChecked属性1就表示选中了,0表示没有选中,因此我们可以通过累计相加这个值来计算购物车选择的产品数:

// 计算购物车选中产品数
let num = arr.reduce((previous,current)=>{return previous + current.isChecked// previous初始值是传入的第二个参数0,current表示数组的当前遍历到的对象
},0)// 通过累计相加所有产品的isChecked的属性值,获得选中的产品数量num为2//计算选中产品总价格,我们也是通过reduce方法累计计算:// 计算购物车选中产品总价格
let price = arr.reduce((previous,current)=>{return previous + current.isChecked * current.cartPrice * current.skuNum// 选中的产品的数量和价格的乘积累计相加},0)// 最终的price的值就是选中产品总价

通过上面的例子我们可以看到这种要累计计算处理数据的情况,使用reduce方法是比较方便的操作。

some和every

因为some()方法和every()方法比较简单,因为比较相似所以这里也是一起讲解。

(1)some()方法用于检测数组中的元素是否满足return的判断条件,如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测;如果没有满足条件的元素,则返回false。

// some方法只要有一个元素符合return的条件就返回true,后面元素就不会再执行判断
let arr = [2,3,4,6]
let result = arr.some((item)=>{return item % 2 === 1 // 判断数组的每个元素是否除以2能余1
})
console.log(result) // 因为第二个元素3符合,所以结果为true

(2)every()方法用于检测数组中的元素是否都满足return的判断条件,只要有一个不符合就会返回false,都符合才返回true。

// every方法要求所有元素符合return的判断条件才返回true,不然就返回false
let arr = [2,3,4,6]
let result = arr.every((item)=>{return item % 2 === 0 // 判断数组的每个元素是否都能被2整除
})
console.log(result) // 因为第二个元素3不符合条件,所以结果为false

总结:

for:简单、可以通过索引访问或者修改原数组

while、do while:循环条件确定,和java一样

for in:可以遍历对象出对象的属性和属性值。

for of:既可以遍历列表也可以遍历对象。可以拿到列表的索引和值,也可以拿到对象的属性和属性值

forEach:省内存,但是不能使用for寻找中的break。可以拿到数组的索引和元素。可以获取对象中的属性值。注意:forEach会改变原来数组中的值。forEach方法没有返回值,一般用于直接修改原数组;

map:不会改变原来数组。但是对于引用数据类型还是会影响原来数组中的对象的属性的。但是可以用过{… 对象}的语法来解决这个问题。map会返回一个数组对象,这个数组对象就是被改变后的对象。

filter:filter()方法用于过滤列表,返回的结果就是过滤后的新数组。这个还是很好用的。

reduce:一般我们用来做累加

some:判断列表中是否有某个元素符合某个规则

every:判断列表中是否全部元素都符合某个规则

注意:js中可以给一个对象直接添加原来没有的属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/527838.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Prometheus】DataModel

数据模型 DataModel 指标 Metric metric 包含 metric name 和 metric label 格式&#xff1a; <metric name>{<label name><label value>, ...}例如&#xff1a;服务器 HTTP 接口 /messages 的总请求数 api_http_requests_total{method"POST",…

Vue3 快速上手从0到1,两小时学会【附源码】

小伙伴们好&#xff0c;欢迎关注&#xff0c;一起学习&#xff0c;无限进步 以下内容为vue3的学习笔记 项目需要使用到的依赖 npm install axios npm install nanoid vue-router npm install pinia npm install mitt 源码&#xff1a;Gitee 运行 npm install npm run dev需要运…

前端面试练习24.3.8

防抖和节流 防抖&#xff08;Debouncing&#xff09;&#xff1a; 防抖是指在短时间内连续触发同一事件时&#xff0c;只执行最后一次触发的事件处理函数。 在实际应用中&#xff0c;常常用于处理用户输入的搜索框或者滚动事件。例如&#xff0c;当用户连续输入搜索关键词时&am…

靶场:sql-less-18(HTTP头注入)

本文操作环境&#xff1a;Kali-Linux 靶场链接&#xff1a;Less-18 Header Injection- Error Based- string 输入用户名和密码以后&#xff0c;我们发现屏幕上回显了我们的IP地址和我们的User Agent 用hackbar抓取POST包&#xff0c;在用户名和密码的位置判断注入点&#xff0…

c++11语法特性

c11 1.c11发展简介 ​ 第一个比较正式的c标准是1998提出的c98标准。之后定了5年计划&#xff0c;每5年来一次大更新。在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于C03(TC1)主要是对C…

数据分析-Pandas画分布密度图

数据分析-Pandas画分布密度图 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&#xff…

[百度二面]操作系统进程、锁相关面试题

2.22 什么是死锁 在多道程序环境下&#xff0c;多个进程可以竞争有限数量的资源。当一个进程申请资源时&#xff0c;如果这时没有可用资源&#xff0c;那么这个进程进入等待状态。有时&#xff0c;如果所申请的资源被其他等待进程占有&#xff0c;那么该等待进程有可能再也无法…

22.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-加载配置文件到分析工具界面

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;21.配置数据保存…

day-18 长度最小的子数组

运用队列的思维&#xff0c;求出每种满足题意的子数组长度&#xff0c;最小的即为答案&#xff0c;否则返回0 code class Solution {public int minSubArrayLen(int target, int[] nums) {int l0,r0;int ansInteger.MAX_VALUE;int total0;while(r<nums.length){totalnums[r…

哥德巴赫猜想

七十年代末八十年代初&#xff0c;哥德巴赫猜想在中国风靡一时&#xff0c;来源于徐迟的一篇同名报告文学。我还是小孩子&#xff0c;记得大人们叽里咕噜疯传。 “哇&#xff0c;不得了。陈景润证明了1&#xff0b;2&#xff1d;3&#xff0c;离1&#xff0b;1&#xff1d;2就…

【C语言步行梯】分支语句if...else、switch详谈

&#x1f3af;每日努力一点点&#xff0c;技术进步看得见 &#x1f3e0;专栏介绍&#xff1a;【C语言步行梯】专栏用于介绍C语言相关内容&#xff0c;每篇文章将通过图片代码片段网络相关题目的方式编写&#xff0c;欢迎订阅~~ 文章目录 什么是语句&#xff1f;引入分支语句&am…

GO: 快速升级Go版本

由于底层依赖升级了&#xff0c;那我们也要跟着升&#xff0c;go老版本已经不足满足需求了&#xff0c;必须要将版本升级到1.22.0以上 查看当前Go版本 命令查看go版本 go version[rootlocalhost local]# go version go version go1.21.4 linux/amd64 [rootlocalhost local]# …