ES5 增加了 5 个迭代方法,我们可以用他们来代替 for 循环,代码异常清爽。
- forEach
- map
- filter
- every
- some
forEach()
对数组中的每一项运行一个给定的函数,这个方法没有返回值。简单地说,就是对每一项单纯地进行一个操作,没有产生多余的东西。
forEach() 需要传入的是一个被成为回调函数(callback)的参数,就是这个函数对数组的各个元素做点啥。
数组当前项的值
数组当前项的索引
数组对象本身
let arr = ["red", "yellow", "green"];
arr.forEach(function (element, index, array) {
console.log(element, index, array)
})
//output
"red", 0, ["red", "yellow", "green"]
"yellow", 1, ["red", "yellow", "green"]
"green", 2, ["red", "yellow", "green"]
forEach()方法还可以传入第二个参数,这个参数是可选的。如果给 forEach()传递了第二个参数,callback 函数里的 this 将指向这个参数。如果没有传入第二个参数,则 this 指向全局对象(在浏览器是 window 对象),严格模式下是 undefined。比如:
let arr = ["red", "yellow", "green"];
arr.forEach(function (element, index, array, this) {
console.log(element, index, array, this)// 增加了 this 参数
}, "wahaha")
//output
"red", 0, ["red", "yellow", "green"], "wahaha"
"yellow", 1, ["red", "yellow", "green"], "wahaha"
"green", 2, ["red", "yellow", "green"], "wahaha"
可以看得出来,forEach 的功能很像,那么我们来看一下数组求和用 forEach()写是多么简介:
let sum = 0;
[1, 2, 3].forEach(function (element, index, array) {
sum += item;
});
console.log(sum); // 6
这个方法在低版本的 JavaScript 中无法运行,有个博主写了对低版本的兼容[1]:
Array.prototype.forEach = Array.prototype.forEach || function(fn, context){
for (var k = 0, length = this.length; k < length; k++) {
if (typeof fn === "function" && Object.prototype.hasOwnProperty.call(this, k)) {
fn.call(context, this[k], k, this);
}
}
}
map()
对数组中的每一项运行给定的函数,也就是跟 forEach()类似,不改变原有数组的元素。区别是 map()会返回一个新的数组,新数组的元素是回调函数 (callback) 的运行结果。
map()和 forEach()所需的参数都一样,所以我们可以用 map()代替 forEach(),不用返回结果即可,需要返回结果,我们给回调函数加上 return 即可。
不用返回新数组的,只需返回求和结果:
let sum = 0;
[1, 2, 3].map(function (element, index, array) {
sum += element;
});
console.log(sum); // 6
返回新数组:
let sum = 0;
let newArr = [1, 2, 3].map(function (element, index, array) {
sum += element;
return element * 2 // 原数组每项乘以 2
});
console.log(sum); // 6
console.log(newArr); // [2, 4, 6]
对于 map()的低版本拓展:
Array.prototype.map = Array.prototype.map || function (fn, context) {
var arr = [];
if (typeof fn === "function") {
for (var k = 0, length = this.length; k < length; k++) {
arr.push(fn.call(context, this[k], k, this));
}
}
return arr;
};
filter()
对于数组的每一项运行给定的函数,这个函数会返回运行回调函数结果为 true 的项组成的数组。
形象地理解,就是筛选一批特种兵加入联合国维和部队,用 filter()来筛选时,我们设置一些必须符合的条件,比如身高、体重、战斗力,合格的就去执行任务。
用法和参数跟 forEach()、map()差不多,下面看一个示例:
let arr = [0, 1, 2, 3];
let newArr = arr.filter(function (element, index, array) {
return e;
})
let newArr2 = arr.filter(function (element, index, array) {
return e>=2;
})
console.log(newArr); // [1, 2, 3]
console.log(newArr2); // [2, 3]
对 filter()的拓展:
Array.prototype.filter = Array.prototype.filter || function (fn, context) {
var arr = [];
if (typeof fn === "function") {
for (var k = 0, length = this.length; k < length; k++) {
fn.call(context, this[k], k, this) && arr.push(this[k]);
}
}
return arr;
};
every()
对数组的每一项运行给定的回调函数,如果运行完所有的元素,每一个元素的结果都是 true,那么返回 true。
这个方法可以看作是对数组的元素做 “与” 操作,非常严格地执行回调函数,但凡有一个结果是 false,就没戏了(返回 false)。
function isBigEnough(element, index, array) {
return element >= 3;
}
let passed = [0, 4, 5].every(isBigEnough);
let passed2 = [3, 4, 5].every(isBigEnough);
console.log(passed); // false
console.log(passed2); // true
every()的拓展:
Array.prototype.every = Array.prototype.every || function (fn, context) {
var passed = true;
if (typeof fn === "function") {
for (var k = 0, length = this.length; k < length; k++) {
if (passed === false) break;
passed = !!fn.call(context, this[k], k, this);
}
}
return passed;
};
some()
这个跟 every()用法类似,只不过它执行的是 “或” 操作。只要有一个元素返回 true,就皆大欢喜,返回 true 了事。如果全部都是 false,那就无力回天,只能返回 false 了。
function isBigEnough(element, index, array) {
return element >= 3;
}
let passed = [0, 1, 5].every(isBigEnough);
let passed2 = [0, 1, 2].every(isBigEnough);
console.log(passed); // true
console.log(passed2); // false
some()拓展
Array.prototype.some = Array.prototype.some || function (fn, context) {
var passed = false;
if (typeof fn === "function") {
for (var k = 0, length = this.length; k < length; k++) {
if (passed === true) break;
passed = !!fn.call(context, this[k], k, this);
}
}
return passed;
};
欢迎大家关注微信公众号:可视化技术( visteacher )
不仅有前端和可视化,还有算法、源码分析、书籍相送
个人网站:http://blog.kurryluo.com
各个分享平台的 KurryLuo 都是在下。
用心学习,认真生活,努力工作!