Open liangbus opened 4 years ago
forEach() 方法对数组的每个元素执行一次提供的函数。返回值是 undefined forEach 不会改变原数组内容(当然可以在 callback 执行时改变原数组) forEach 遍历的范围在第一次调用 callback 前就会确定。调用 forEach 后添加到数组中的项不会被 callback 访问到。
var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。 map 不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组) map 方法处理数组元素的范围是在 callback 方法第一次调用之前就已经确定了。调用map方法之后追加的数组元素不会被callback访问。
var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])
对 reduce 的理解,与其说是遍历,更不如说是一个累计器,因为通过它对一个数组做一些累计性的操作更常见
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
其返回值,就是累计最终的结果
需要注意的是,如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。
比如二维数组的扁平化就可以通过 reduce 来简单实现
[[0, 1], [2, 3], [4, 5]].reduce(
(acc, b) => {
return acc.concat(b);
},
[]
);
// [0, 1, 2, 3, 4, 5]
除非遍历的是对象,指针不改变,对象内容可以改变
for, for-in, for-of
for
这个应该是学编程的时候,循环的初认识吧,最基础的 for 循环其结构为
其中初始化,条件语句,final-expression 都是可以省略的,但须要确保正确跳出循环,以免陷入死循环 statement 中可以使用 break 和 continue 关键字退出和跳过本次循环 要注意的是,在初始化阶段,应该尽量避免使用 var 去声明变量,由于 ES5 没有块级作用域,所以 var 会把声明上升,因而有可能会出现变量污染,比如很常见的一道题
改成 let 就可以使该循环正常输出 0-9,let 实际上为 JavaScript 新增了块级作用域。 普通 for 循环由于初始化和条件语句都是由开发者自行决定,所以就没有太多使用限制
for-in
for-in 一般用来遍历对象,而非遍历数组(虽然它可以用来遍历数组),因为通常数组的遍历是需要升序的,但它不能保证这一点,并且它返回的 key 为字符串,若以 key 做一些计算,可能会引起一些不必要的麻烦,并且,假如有通过 prototype 拓展了 Array 的原型,如果没有设置该属性是否可枚举,则通过 for-in 循环时,会将其一并遍历,如下:
for...in 循环会像 [[Getter]] 一样从原型链上查找属性,所以只要其原型上有相应的可枚举属性,for...in 都能遍历到,如下
continue 和 break 对 for-in 是无效的
for-of
相比 for-in, for-of 可以遍历更多的迭代器,诸如 Map, Set, arguments 对象, String(相比以前,就省去了 string 转数组这一步了),for-of 可以使用 continue, break, throw, return 等跳出循环
for...of 还能遍历我们自定义的迭代器,只要其有 [Symbol.iterator] 属性
举个例子
for...of 会自动调用 next 函数然后读取其返回的 value 值,并且根据 done 属性决定是否继续遍历,上面的示例就是输出 1到100 的数字