0x00 前言
看公司项目源码的时候看到一个forEach
方法,故往MDN了解一下,然后在MDN的介绍里又看到for...of
、for...in
、map
,在此总结一下它们的特性、区别及如何选择该用哪个
0x01 Array.prototype.map()
map()
方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
参数
callback
生成新数组元素的函数,使用三个参数:currentValue
callback
数组中正在处理的当前元素。index
可选
callback
数组中正在处理的当前元素的索引。array
可选
map
方法调用的数组。
thisArg
可选
执行callback
函数时值被用作this
。
因为map
生成一个新数组,当你不打算使用返回的新数组却使用map
是违背设计初衷的,请用forEach
或者for-of
替代。你不该使用map
: A)你不打算使用返回的新数组,或/且 B) 你没有从回调函数中返回值
0x02 Array.prototype.forEach()
forEach()
方法对数组的每个元素执行一次给定的函数
可依次向 callback
函数传入三个参数:
- 数组当前项的值
- 数组当前项的索引(可选)
- 数组对象本身(可选)
forEach()
为每个数组元素执行一次 callback
函数;与 map()
或者 reduce()
不同的是,它总是返回 undefined
值,并且不可链式调用。其典型用例是在一个调用链的最后执行副作用(side effects,函数式编程上,指函数进行 返回结果值 以外的操作)。
forEach()
被调用时,不会改变原数组,也就是调用它的数组(尽管 callback
函数在被调用时可能会改变原数组)。(译注:此处说法可能不够明确,具体可参考EMCA语言规范:’forEach
does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn
.’,即 forEach
不会直接改变调用它的对象,但是那个对象可能会被 callback
函数改变。)
注意: 除了抛出异常以外,没有办法中止或跳出 forEach()
循环。如果你需要中止或跳出循环,forEach()
方法不是应当使用的工具。
若你需要提前终止循环,你可以使用:
- 一个简单的
for
循环 for...of
/for...in
循环Array.prototype.every()
Array.prototype.some()
Array.prototype.find()
Array.prototype.findIndex()
译者注:只要条件允许,也可以使用 filter()
提前过滤出需要遍历的部分,再用 forEach()
处理。
0x03 for...of
for...of
语句在可迭代对象(包括 Array
,Map
,Set
,String
,TypedArray
,arguments
对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句
无论是for...in
还是for...of
语句都是迭代一些东西。它们之间的主要区别在于它们的迭代方式
for...in
语句以任意顺序迭代对象的可枚举属性
for...of
语句遍历可迭代对象定义要迭代的数据
0x04 for...in
for...in
语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性
提示:for...in
不应该用于迭代一个关注索引顺序的 Array
for ... in
是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()
和for ... of
,那么for ... in
的到底有什么用呢?
它最常用的地方应该是用于调试,可以更方便的去检查对象属性(通过输出到控制台或其他方式)。尽管对于处理存储数据,数组更实用些,但是你在处理有key-value数据(比如属性用作“键”),需要检查其中的任何键是否为某值的情况时,还是推荐用for ... in
0xff 总结
1. forEach
- 针对数组
- 总是返回
undefined
值 - 没有办法中止或跳出
forEach()
循环
2. map
- 针对数组
- 不打算使用返回的新数组却使用
map
是违背设计初衷的
3. for...of
针对可迭代对象(包括 Array
,Map
,Set
,String
,TypedArray
,arguments
对象等等)
4. for...in
针对对象
5. 如何选择
针对对象 |
for...in
|
||
---|---|---|---|
针对数组 | 需要返回新数组 |
map
|
|
不需要返回新数组 | 需要中止或跳出循环 |
for...of
|
|
for 循环 | |||
不需要中止或跳出循环: |
forEach
|
||
for...of | |||
for 循环 |
//End of Article
参考文献
- for…in - JavaScript | MDN (developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for…in)
- for…of - JavaScript | MDN (developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for…of)
- Array.prototype.forEach() - JavaScript | MDN (developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
- Array.prototype.map() - JavaScript | MDN (developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map)