JS之map、forEach、filter

Array.prototype.map

一、map()概念

定义:map()创建一个新数组,其中的元素是原数组元素调用一个函数处理后的结果。

  • 会按照原数组的顺序处理元素。
  • 不会对空数组进行检测。
  • “创建”,也就是说它不会改变原数组的内容。
  • 处理数组时,数组元素的范围是在 callback 方法第一次调用之前确定。在 map()执行过程中:原数组中新增加的元素将不会被 callback 访问到;若已经存在的元素被改变或删除了,则它们的传递到 callback 的值是 map()遍历到它们的那一时刻的值;而被删除的元素将不会被访问到。
  • 当不打算使用返回的新数组,或没有从回调函数中返回值时,不建议用map()。
  • 没有办法中止或者跳出map() 循环,即不可用return、break。
  • 使用箭头函数,thisArg 参数会被忽略。
二、语法

array.map(function(currentValue, index, arr), thisValue)

  • currentValue: 必选,当前元素的的值。
  • index: 可选,当前元素的索引.
  • arr: 可选,当前元素所属的数组对象。
  • thisValue: 可选,对象作为该执行回调时使用,传递给函数,用作 “this” 的值。如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。
三、举个简单的栗子
var arr = [1,2,3,4,5];
var map01 = arr.map(x=>x*x);
console.log(map01);  //(5) [1, 4, 9, 16, 25]
四、易错的例子

【MDN】map 方法中的 callback 函数只有一个参数是必需的,就是正在被遍历的当前数组元素本身。但这并不意味着 map 只给 callback 传了一个参数。这个思维惯性可能会让我们犯一个很容易犯的错误。看这个例子:

["1", "2", "3"].map(parseInt);

结果是[1,NaN,NaN],而不是[1,2,3]!!

这是因为parseInt函数是有两个参数的,第一个是要转为整数的表达式,第二个是转换的基数(一个在2~36范围内的数),而在这里第二个参数本来是回调函数中的index参数。

parseInt(string, radix) -> map(parseInt(value, index))

first iteration (index is 0): parseInt(“1”, 0); // 忽略0,结果:1

second iteration (index is 1): parseInt(“2”, 1); // 不可能有1进制,结果:NaN

third iteration (index is 2): parseInt(“3”, 2); // 二进制得不到3,结果:NaN

解决办法:

  • 写一个在内部已经指定了parseInt方法转换进制的函数;
  • 使用箭头函数语法,其实就是为parseInt()指定只有一个参数
['1', '2', '3'].map( str => parseInt(str) );
  • 改为使用number(),但要注意二者的区别。
五、兼容旧环境

map被添加到第5版的ECMA-262标准中;因此,它可能不存在于标准的所有实现中。可以通过在脚本开头插入以下代码来解决此问题
查看MDN

Array.prototype.forEach()

一、概念

forEach() 方法对数组的每个元素执行一次提供的函数。

  • 升序为数组中含有效值的每一项执行一次callback函数。
  • 那些已删除或者未初始化的项将被跳过。
  • 同样不会改变原数组的值(但是callback可能会改变原数组)。
  • 总是返回 undefined 值,并且不可链式调用!
  • 遍历的范围在第一次调用 callback 前就会确定。调用 forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach 遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()),之后的元素将被跳过。
  • 没有办法中止或者跳出 forEach() 循环,即不可用return、break。
  • 使用箭头函数,thisArg 参数会被忽略。
二、语法
array.forEach(callback(currentValue, index, array) {
  // do something
}, thisArg)

参数含义与map()的相同

三、例子

来看一个迭代时被删除的例子

var words = ['one', 'two', 'three', 'four'];
words.forEach(function(word) {
  console.log(word);
  if (word === 'two') {
    words.shift();
  }
}); 
// one two four

因为第二项被删除,后面的项都往前移了,three变成刚刚已经遍历过的索引为1的项,被跳过。

使用箭头函数的例子

var arr = [1, 2, 3];

arr.forEach((v, i, arr) => {   //或用 map
  console.log(this);
}, arr)

// window
// window
// window
四、兼容旧版本

forEach 是在第五版本里被添加到 ECMA-262 标准的;这样它可能在标准的其他实现中不存在,可以在调用 forEach 之前 插入下面的代码,在本地不支持的情况下使用 forEach()。该算法是 ECMA-262 第5版中指定的算法。查看MDN

map与forEach的区别

由上可以看到,它们基本上可以互换。最主要的区别在于,map()会分配内存空间存储新数组并返回,不会改变原来的数组,而forEach()不返回,但允许callback更改原始数组的元素。

Array.prototype.filter()

一、概念

定义:filter() 方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素。

  • 返回一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。
  • 不会改变原数组。
  • 遍历的元素范围在第一次调用 callback 之前就已经确定了。在调用 filter 之后被添加到数组中的元素不会被 filter 遍历到。如果已经存在的元素被改变了,则他们传入 callback 的值是 filter 遍历到它们那一刻的值。被删除或从来未被赋值的元素不会被遍历到。
二、语法[MDN]
var newArray = arr.filter(callback(element, index, array), thisArg)
  • callback: 用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。
  • element: 数组中当前正在处理的元素。
  • index: 可选,正在处理的元素在数组中的索引。
  • array: 可选,调用了 filter 的数组本身。
  • thisArg: 可选,执行 callback 时,用于 this 的值。否则,callback 的 this 值在非严格模式下将是全局对象,严格模式下为 undefined。callback 函数最终观察到的 this 值是根据通常函数所看到的 "this"的规则确定的。
三、简单的例子
var f = [1, 2, 3, 4].filter(function(f) {
  return f >= 3;
});
console.log(f);
// [3, 4]
四、兼容旧版本

filter 被添加到 ECMA-262 标准第 5 版中,因此在某些实现环境中不被支持。可以把下面的代码插入到脚本的开头来解决此问题,该代码允许在那些没有原生支持 filter 的实现环境中使用它。该算法是 ECMA-262 第 5 版中指定的算法。查询MDN

Array.prototype.some()&Array.prototype.every()

那顺便讲一下some()和every()吧hhh~

一、语法
array.some(function(currentValue,index,arr),thisValue)
array.every(function(currentValue,index,arr),thisValue)

同样也只有currentValue是必需的,含义参考以上方法的参数含义,很好理解啦。

二、概念
  • 两个方法都返会布尔值。some()测试数组中是否存在某个元素符合回调函数,找到这个元素之后返回true,并且不会再继续测试之后的元素,否则返回false。every()测试数组中是否所有元素都符合回调函数,若找到一个元素不符合,则返回false,并且不再测试之后的元素,否则返回true。
  • 两个方法都不会改变原数组。
  • 两个方法都不会对空数组进行检测。
  • 在es5时才被加入为标准,要考虑兼容问题(IE、firefox)
发布了12 篇原创文章 · 获赞 3 · 访问量 276

猜你喜欢

转载自blog.csdn.net/CcA_Lin/article/details/102829577