forEach:循环遍历数组的每一项,不改变数组
写法:
数组对象.forEach(function(数组当前项的值,数组当前项的索引,数组对象本身)){
// Do something,forEach是没有返回值,返回值为undefined,并且不可链式调用
}}
实例:
let obj = {
"data": [
{ "id": 1, "name": "苹果" },
{ "id": 2, "name": "香蕉" },
{ "id": 3, "name": "桃子" }
],
};
let newArrs = [];
obj.data.forEach(function (item, index, originArrs) {
console.log(item, index, originArrs, '---lemon');
newArrs.push(item.name);
})
console.log(newArrs);
map:返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组,会分配内存空间存储新数组并返回
写法:
数组对象.map(callback(数组当前项的值,数组当前项的索引,数组对象本身){{
// Do something,必须要有返回值,如果不给return,它会返回一个undefined
// 它不会影响原数组,只是将原来的数组拷贝了一份,把拷贝的数组项进行更改,支持链式调用
return xxx;
}}
实例: 假定有一个对象数组(originArrs),将originArrs数组中对象某个属性的值存储到B数组中
let originArrs = [
{ "id": 1, "name": "苹果", price: 80, color: "红色" },
{ "id": 2, "name": "香蕉", price: 50, color: "黄色" },
{ "id": 3, "name": "桃子", price: 100, color: "粉色" }
]
let sum = 0;
let newArrs = originArrs.map(function (item, index, arr) {
console.log(item, index, arr, '---lemon');
return item.price;
}); // 也可以直接在这后面链式调用,跟着forEach的
console.log(newArrs);
newArrs.forEach(function (price, index, arr) {
sum += price;
});
console.log(sum);
filter:它不会改变原有数组,返回的是过滤后的新数组, 在调用filter之后添加到数组中的元素不会被filter遍历到。
写法:回调函数返回的结果一个boolean值,若结果为真,则返回匹配的项;否则,返回一个空数组。
数组对象.filter(function(数组当前项的值,数组当前项的索引,数组对象本身)){
// Do something,可链式调用
// filter函数遍历的元素范围在第一次调用回调函数callback的时候就已经确定
}
实例: 假定有一个对象数组(originArrs),获取数组中指定类型的对象放到B数组中
let originArrs = [
{ "id": 1, "name": "苹果", price: 80, type: "水果" },
{ "id": 2, "name": "香蕉", price: 50, type: "水果" },
{ "id": 3, "name": "桃子", price: 100, type: "水果", favourite: 'ture' },
{ "id": 4, "name": "猫咪", price: 10000, type: "动物" },
{ "id": 5, "name": "狗狗", price: 15000, type: "动物" },
{ "id": 6, "name": "沙糖桔", price: 150, type: "水果", favourite: 'ture' }
];
/* 实例1:假定有一个对象数组(originArrs),将originArrs数组中对象某个属性的值存储到B数组中*/
let filterTypeArr = originArrs.filter(function (item, index, arrs) {
return item.type == "水果";
})
console.log(filterTypeArr, '这些都属于水果类型哦~')
/* 实例2:找到满足originArrs数组对象中是否包含favourite的属性并且价格不大于140 */
let filterFun = originArrs.filter(function (item) {
//hasOwnProperty()方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性
return item.hasOwnProperty("favourite") && item.price <= 140;
})
console.log(filterFun, '我满足条件啦~,都不满足的话我就是个空数组');
forEach、map、filter综合使用
综合实例:有两个对象根据对象A中id值,过滤掉B数组中不符合的数据(根据条件抽取出要操作对象中的属性)
/* 在originArrs里面找出与obj对象的type类型一样的属性形成一个新的数组newArray */
let originArrs = [
{ "id": 1, "name": "苹果", price: 80, type: "水果" },
{ "id": 2, "name": "香蕉", price: 50, type: "水果" },
{ "id": 3, "name": "桃子", price: 100, type: "水果", favourite: 'ture' },
{ "id": 4, "name": "猫咪", price: 10000, type: "动物" },
{ "id": 5, "name": "狗狗", price: 15000, type: "动物" },
{ "id": 6, "name": "沙糖桔", price: 150, type: "水果", favourite: 'ture' }
];
let obj = { "id": 7, "name": "葡萄", price: 150, type: "水果" };
let newArray = [];
let filterFun = function (obj, originArrs) {
return originArrs.filter(function (item) {
return item.type == obj.type;
}).map(function (currentVal) {
console.log(currentVal, '我是map要遍历的值!');
return currentVal.name;
}).forEach(function (curr) {
newArray.push(curr)
console.log(newArray, '我是在forEach循环遍历后新生成的数组!');
})
};
console.log(filterFun(obj, originArrs));
find:用来查找目标元素,若找到就返回该元素,否则返回undefined,不会改变原有数组。找到第一个符合条件的就不会再往后找了。
写法:
数组.find(数组当前项的值,数组当前项的索引,数组本身)
//与filter过滤区别:find方法比较快速便捷,找到第一个符合条件之后,就不会往后找了;
//返回值:若匿名回调函数结果为真,则返回所匹配的选项对象,否则返回undefined
实例: 在originArrs里面找出第一个与obj对象的type类型一样的属性形成一个新的数组newArray
// 在originArrs里面找出第一个与obj对象的type类型一样的属性形成一个新的数组newArray
let originArrs = [
{ "id": 1, "name": "苹果", price: 80, type: "水果" },
{ "id": 2, "name": "香蕉", price: 50, type: "水果" },
{ "id": 3, "name": "桃子", price: 100, type: "水果", favourite: 'ture' },
{ "id": 4, "name": "猫咪", price: 10000, type: "动物" },
{ "id": 5, "name": "狗狗", price: 15000, type: "动物" },
{ "id": 6, "name": "沙糖桔", price: 150, type: "水果", favourite: 'ture' }
];
let obj = { "id": 7, "name": "葡萄", price: 150, type: "水果" };
let filterFun = function (obj, originArrs) {
console.log(obj, originArrs, '---lemon');
return originArrs.find(function (item) {
return item.type == obj.type;
})
};
console.log(filterFun(obj, originArrs), '我是第一个满足条件的耶~');
与for循环比较
性能上:for循环>forEach>map
可读性: forEach/map>for循环
区别: for循环是按顺序遍历,按照下标索引的方式进行读取访问元素的,随机访问,而forEach/map等是使用iterator迭代器进行遍历,先取到数组中的每一项的地址放入到队列中,然后按顺序取出队里的地址来访问元素。