学习es6循环心得(借鉴学习:damon的es6学习之路)

https://blog.csdn.net/qq_26332449/article/details/94554485?spm=1001.2014.3001.5502

1、九种常用的es6循环:

1、forEach循环

2、some循环

3、every循环

4、indexof循环

5、lastIndexOf循环

6、reduce循环

7、reduceRight循环

8、filter循环

9、map循环

在循环学习过程中,常用的循环就是fifter循环和map循环,这两个循环很好的替代了for循环,所以我用了红色的字体标记,后面会对这两个循环做出更加细致的解释。

2、九种循环的使用和实例介绍

a、forEach循环

forEach循环的类型是一个函数:

console.log(tepeof [].forEach)

// 这里的返回值是一个function

forEach循环的应该方法是:数组.forEach(){},小括号里面是forEach函数里面的三个参数,大括号里面是你循环需要做的操作,就是循环体,实例如下:

const list = [1, 2, 3, 4];
list.forEach(console.log) 

// 结果:

// 1,0[1,2,3,4]
// 2,1[1,2,3,4]
// 3,2[1,2,3,4]
// 4,3[1,2,3,4]

在这里我对这段代码的解释就是:他遍历了这个数组,然后数组的长度是4,所以他遍历了4次,结果最前方的1,2,3,4应该就是遍历的次数,也就是数组长度,后面的0,1,2,3就是数组下标,后面的数组【1.2.3.4】就是遍历的数组本体,由此可以推断,forEach循环他的本体样子应该是有入参的,入参应该是三个值,就是现在所显示的三个值:数组长度,数组下标,数组本身,然后这个地方出现了一个疑问,就是为什么.console.log的时候为什么不能加括号,加了括号就报错,报错内容为:undefined is not a function

脑雾1:为什么console.log的时候会报错

[].forEach(function(array.length,array.index,array)){
    // 内容
}

为了证实我的想法,举一反三,于是我又写了另外一个不是数字的数组去用forEach遍历新的数组:

const list1 = ['许老师', '老张', '李老师']
list1.forEach(console.log)


// 结果:


// 许老师  0 ['许老师', '老张', '李老师']
// 老张 1 ['许老师', '老张', '李老师']
// 李老师  0 ['许老师', '老张', '李老师']



那么我上面的猜想就错了,最开始的值并不是数组的长度,而是数组里面的内容,数组长度是本来就规定好的,所以forEach循环没必要把数组长度展现出来,那么,现在正确的答案就出来了,forEach循环的本体应该是这样的:里面的三个值应该是,数组内容,数组下标,数组本体

[].forEach(function(array.value,array.index,array)){
    // 内容
}

在许老师的文档中我看到了一个词,叫做回调函数,forEach就是一个回调函数,回调函数这个词语在我的脑海里面并没有任何的实质性理解,所以,在看这篇文章之前,许老师用chatGPT给我解释了回调函数的大概意思,就是正常的函数调用结束后,这个函数体就已经结束了,而回调函数是在主函数运行完成的时候,再去调用函数内部的函数,并且回调函数里面的this指向也有一定的说法,回调函数在我这还是有些脑雾,希望未来的工作中应用起来可以解除脑雾!

脑雾2:回调函数

forEach循环的实例,我直接引用许老师文档中的例子,就不自己去写了,引入进来再去理解:

var sum = 0;

[1, 2, 3, 4].forEach(function (item, index, array) {
  sum += item;
});

alert(sum); // 10

其实看到这个例子的时候我是有脑雾的,为什么会等于10,于是我自己去演算了一遍整个循环的过程,于是脑路也就清晰了:首先,sum赋值为0,那么这个时候sum的值是0,然后forEach循环了一个数组,数组里面的值分别是1,2,3,4,我们前文已经说过了,forEach循环函数的第一个值为遍历数组的内容,所以,item === 1,2,3,4,那么sum+=item,过程就是0+1+2+3+4,结果就是10.

forEach除了有回调函数以外,还可以改变函数里面的this指向,去上下文找到指向的值,例子如下:

  var database = {
    users: ["张含韵", "江一燕", "李小璐"],
    sendEmail: function (user) {
      console.log(this, '1');
      if (this.isValidUser(user)) {
        console.log("你好," + user);
      } else {
        console.log("抱歉," + user + ",你不是本家人");
      }
    },
    isValidUser: function (user) {
      return /^李/.test(user);
    }
  };

  // 给每个人法邮件
  database.users.forEach(  // database.users中人遍历
    database.sendEmail,    // 发送邮件
    database               // 使用database代替上面标红的this
  );

  // 结果:
  // 你好,张含韵
  // 抱歉,江一燕,你不是本家人
  // 抱歉,李小璐,你不是本家

这个地方,this的指向就是最外层的对象database,所以哪怕this.isValidUser这个属性写在了全文的下方,在上方的this也是可以找到的,这里面涉及到了两个问题,this的指向性问题,这个问题大概是可以理解到的,还有一点就是用到了正则表达式 /^/,这个东西是我从来没有接触过的东西,他有文档,以后在学完后,会去深入研究

脑雾3:正则表达式

forEach循环是不是遍历不存在的元素的,如果这个元素是undefind或者null,那么就不会显示出来,例子如下:

  var array = [1, 2, 3];

  delete array[1]; // 移除 2
  console.log(array);; // "1,,3"

  console.log(array.length); // but the length is still 3

  array.forEach(alert); // 弹出的仅仅是1和3

这里我们把array数组中的2删除了,那么再次打印这个数组的话,数组中就只有两个值,是1和3,但是数组下标依旧是3,因为2被删除后,变成了undefined,而forEach不会遍历不存在的数组,通俗的讲就是forEach不会遍历纯粹“占着官位吃空饷”的元素。

下面我去证明一下为什么这个数组中的2虽然被删除了,但是数组长度依旧为三:

  for (let i = 0; i < array.length; i++) {
    console.log(array[i]);
  }


// 结果:


  1
  undefined
  3

b、some循环

some循环我的理解是在一个数组中找满足条件的元素,如果找到返回true,类似与indexOf,因为indexOf也是一个寻找对象的判断基础,他的用法类似于forEach

array.some(callback,[thisObject])

下面在许老师的文档中找到一个例子:

var scores = [5, 8, 3, 10];
var current = 7;

function higherThanCurrent(score) {
  return score > current;
}

if (scores.some(higherThanCurrent)) {
  alert("朕准了!");
}

这段代码的意思就是:创建一个数组scores,里面四个值:5,8,3,10,创建另一个变量,赋值为7,创建一个函数,入参为score,函数体内部返回一个对比,score>current,函数下方开始判断,先用some遍历数组scores,并将函数当做回调函数传入,如果score里面有值大于current变量的值7,那么直接alert一个字符串,这里,函数的入参score就已经传参了scores里面的值。但是他只会返回一次true,当他返回的值为true的时候,直接停止循环,不会继续向下找。

c、every循环

every和some循环有异曲同工之妙,他们的不同在于,遍历数组时,判断条件必须全部等于true,他才会返回true,否则返回false

  if (scores.every(higherThanCurrent)) {
    console.log("朕准了!");
  } else {
    console.log("来人,拖出去斩了!");
  }

// 结果:来人,拖出去斩了

d、indexOf循环

indexof循环主要用于寻找数组中的值,或者返回整数的数组下标,如果没有匹配的条件,则返回-1.fromIndex可以选择,就是在那个位置开始搜索,默认值为0

array.indexOf(searchElement[,fromIndex])
var data = [2, 5, 7, 3, 5];

console.log(data.indexOf(5, "x")); // 1 ("x"被忽略)
console.log(data.indexOf(5, "3")); // 4 (从3号位开始搜索)

console.log(data.indexOf(4)); // -1 (未找到)
console.log(data.indexOf("5")); // -1 (未找到,因为5 !== "5")

indexOf的应该是白话一点就是,数组.indexOf(寻找的值,'从哪里开始,这里是数组下标'),数组下标可以加引号,可以不加引号,我建议加引号,方便观看和区分

e、lastIndexOf

和意思一样,这个和indexOf基本一样,只是这个是从数组后面往前面找,并且fromIndex的值是array.length - 1,大概意思如下:

var data = [2, 5, 7, 3, 5];

console.log(data.lastIndexOf(5)); // 4
console.log(data.lastIndexOf(5, 3)); // 1 (从后往前,索引值小于3的开始搜索)

console.log(data.lastIndexOf(4)); // -1 (未找到)

f、reduce循环

reduce循环的主要作用应该是对于前后数据的算法,reduce的回调函数接收四个参数,分别是:previous,current,index,array,这四个值分别是之前值,当前值,索引值和数组本身,initialValue参数可选,表示初始值,如果指定的话,那么previous就被当做最开始的初始值,如果缺省,则使用当前数组中的第一个元素当做provious的初始值,同时current往后排一位。相比有initialValue值少一次迭代(循环),下面是例子:

var sum = [1, 2, 3, 4].reduce(function (previous, current, index, array) {
  return previous + current;
});

console.log(sum); // 10

因为reduce是循环,所以会重复循环体内的操作,一直到操作结束,所以这里的表达式的直观理解就是:provious + current,最开始provious的初始值为1,current为2,这里为1+2为3,第二次,provious的初始值变成了3,current顺延变成了3,所以是3+3为6,第三次provious的初始值变成了6,那么就是6+4为10,循环结束,这里sum的值就变成了10,相当于前一个值(对象)跟下一个值进行操作,得到的值(对象)再跟下一个值(对象)进行操作,这里current是在顺延数组里面的元素,而provious的值是操作后的结果。

下面是对这个循环进行的解释:

这里的原文解释和我的理解基本上没有太大的出入,只是我没理解到怎么退出的圆环,看了解释后完全明白了,循环结束就是当current的值变成undefined的时候,退出循环。

reduce循环还有一个二维数组扁平化,准确来说就是合并多个数组为一个,代码如下:

var matrix = [
  [1, 2],
  [3, 4],
  [5, 6]
];

// 二维数组扁平化
var flatten = matrix.reduce(function (previous, current) {
  return previous.concat(current);
});

console.log(flatten); // [1, 2, 3, 4, 5, 6]

将prevent和current进行连接,那么最终matrix里面的三个数组的值,就会合并到一个数组里面,这个我现在比较模糊,希望后面的学习可以了解到这个到底是什么意思

脑雾4:二维数组扁平化

g、reduceRight循环

reduceRight循环和reduce循环基本类似,只不过他也是从后向前开始实现,例子:

var data = [1, 2, 3, 4];
var specialDiff = data.reduceRight(function (previous, current, index) {
  if (index == 0) {
    return previous + current;
  }
  return previous - current;
});

console.log(specialDiff); // 0

实现逻辑:

第一次循环,provious为4,current为3, 4 - 3 = 1

第二次循环,provious为1,current为2, 1 - 2 = -1

第三次循环,provious为-1,current为1,但是数组下标为0,所以触发判断-1 + 1 = 0

第四次循环,current为undefined,退出循环

h、fifter循环

fifter循环的主要作用是“筛选”和“过滤”,就是字面意思,他所得到的值会放入一个新的数组里面

array.filter(callback,[ thisObject]);

他的回调函数是需要return值的,他return的时候会进行判断,如果不满足条件,就会被遗弃,意思就是true添加,false过滤,实例如下:

var data = [0, 1, 2, 3];
var arrayFilter = data.filter(function(item) {
    return item;
});
console.log(arrayFilter); // [1, 2, 3]

在这个地方,有一个问题我没搞懂,因为在循环data数组的时候,里面的四个值为0,1,2,3,但是return item的时候,打印出来的确实1,2,3,这个问题许老师给我的解释是,fifter在打印前,return后面的表达式是属于一个判断,如果为false则直接过滤,而数字0,undefined和null在判断中默认为false,直接被filter循环过滤,所以这里给的结果是return item为[1,2.3]

举个例子:

  const list3 = [0, 1]
  if (list3.length) console.log(true, 1);
  const list4 = []
  if (list4.length) console.log(true, 2);
  if (undefined) console.log(true, 3);


// 结果:只会打印出来  true,1
// 因为后面的空数组长度为0,默认false,undefined,默认为false
 let array1 = [1, 2, 3, 4];
  let arrayFilter1 = array1.filter(function (item) {
    return item > 1
  })
  console.log(arrayFilter1);  // 结果为[2,3,4]

这里值得一提的是,返回值只要是弱等于 == true//false就可以,不一定非得返回 === true//false

i、map循环

map循环和forEach循环很像,他的表达式:

array.map(callback,[ thisObject]);

并且默认的回调函数也和forEach是一模一样的:

[].map(function(value, index, array) {
    // ...
});

map循环和forEach循环的区别就是forEach循环只是遍历数组,而mao是讲原数组遍历,然后进行操作后放入到一个新数组中,相当于一次数组深复制,他的calllbacj是要有返回值的,就是return值

var data = [1, 2, 3, 4];

var arrayOfSquares = data.map(function (item) {
  return item * item;
});

alert(arrayOfSquares); // 1, 4, 9, 16

如果callback没有返回值,没有return值,那么所有的值都会被映射成undefined。

实际的使用中,mao循环可以直接使用到对象数组中的特指参数:

var users = [
  {name: "张含韵", "email": "zhang@email.com"},
  {name: "江一燕",   "email": "jiang@email.com"},
  {name: "李小璐",  "email": "li@email.com"}
];

var emails = users.map(function (item) { return item.email; });

console.log(emails.join(", ")); // zhang@email.com, jiang@email.com, li@email.com

map循环的返回值一定是一个数组

map循环可以写成箭头函数,看起来更加的简洁明了:

const array = [].map((item,index,value) =>{
    // return 返回值
})

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值