学习 JavaScript (十) 数组迭代(遍历)方法,让我们抛弃 for 循环

猴.jpg

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;
};


image

欢迎大家关注微信公众号:可视化技术( visteacher )

不仅有前端和可视化,还有算法、源码分析、书籍相送

个人网站:http://blog.kurryluo.com

各个分享平台的 KurryLuo 都是在下。

用心学习,认真生活,努力工作!

你可能感兴趣的:(学习 JavaScript (十) 数组迭代(遍历)方法,让我们抛弃 for 循环)