ECMAScript6--高阶函数以及遍历

297 阅读4分钟

Iterator

为什么先讲这个Iterator呢?因为for..of循环的本质就是调用Iterator接口。

Iterator的本质

Iterator是一个接口,所谓接口就是数据结构的入口,通过这个接口就可以访问它。它其实就是一个遍历器对象,为不同的数据结构提供了统一的访问方法,任何部署了这一接口的数据结构我们都可以对他进行遍历操作。

Iterator的内部过程

  1. 创建了一个指针对象指向数据结构的起始位置
  2. 调用对象的next方法指向第一个成员 每次调用都会有两个返回值,一个是成员值,还有一个是bool值,这个bool值就是判断有没有遍历到最后一个,下一次还要不要调用next方法
  3. 如此反复,直到遍历到最后一个成员。

存在Iterator接口的数据结构

  • 数组
  • 类数组对象
  • String
  • Map/Set

**他们都是自带这个接口的,配置在Symbol.iterator方法里面,这个方法会生成一个遍历器对象。**我举个简单的例子,你可以在数组的原型中找到它,Array.prototype一直往下翻就能找到它。

注意

Object对象是不自带这个接口的,为什么呢?Object遍历的顺序是不确定的。所以它没有自带的iterator接口,不过你可以自己给她绑定。

for...of循环(以及for..in循环)

上文说到,for...of循环的本质就是调用这个Iterator接口,所以但凡有这个接口的数据结构都能使用for...of进行遍历。换言之,没有这个接口的数据结构使用它进行遍历就会报错。没错我说的就是Object对象。 报错:obj并不是可以迭代的。

for..of和for...in的对比

for..of获取的是值,而不是索引。比如for...of遍历数组获取的就是数组的元素,而for,,,in遍历数组获取的是数组的索引(并且不是number类型,而是String类型),**其实for..in本质上是为了遍历对象服务的,并且它遍历获取的是key值。**而for...of主要为数组服务。

for...of和forEach对比

forEach不能中途跳出循环(break)。

注意

在v-for指令中,我亲身实践v-for in/of是没有区别的。

map方法

要点

遍历数组,使数组的每一个元素都执行参数中的回调函数,再把返回值组成一个新的数组。注意他不会改变原数组。

范式

arr.map(function(n,[index,[arr]]){}),map参数是一个回调函数。

  • 回调函数的第一个参数是当前遍历获取的数组某个元素,必选
  • 第二个参数是该元素的index值,可选
  • 第三个是遍历的数组,可选
    回调函数每次执行都会return一个值,等遍历完成后,这些值就组成了一个新的数组。

example

将当前数组的元素放大二倍

let arr = [1,2,3];
arr.map(function(n){return n*2})//arr.map(n=>2*n)得到了一个新数组

filter方法

要点

过滤掉数组的某些元素,把符合条件的元素,保留下来,组成一个新数组。这个方法也不会改变原数组还有就是这个方法的回调函数的返回值必须是一个bool值,只有bool值为true的时候,才将其保留下来,为false的话就过滤掉。

范式

arr.filter(function(n,[index,[arr]]){}),filter参数是一个回调函数。

  • 回调函数的第一个参数是当前遍历获取的数组某个元素,必选
  • 第二个参数是该元素的index值,可选
  • 第三个是遍历的数组,可选

example

获取数组中大于20的元素

let arr = [5,58,9,41];
arr.filter(n=>n>20);//符合条件的数组成一个新数组。不会改变原数组

reduce方法

要点

这个方法比较特别。为什么呢?因为这个总是来做一些汇总操作的,要不就是对所有元素求和啦,要不就是对所有元素求积啦等等。

范式

arr.redcuce(function(pre,n,[index,[arr]]){},[initialValue])reduce有两个参数:第一个参数是回调函数,必选。第二个参数,是初始值,可选。
回调函数有四个参数:

  • 第一个参数是上次回调函数的返回值,或者是初始值(第一次的时候),必选
  • 第二个参数是这次遍历到的元素,必选
  • 第三个参数是元素的索引值,可选
  • 第四个参数是遍历的数组,可选

example

求所有元素的平方的和。

let arr = [1,2,3];
arr.reduce(function(pre,n)
{return pre+n*n},0)//14