zoukankan      html  css  js  c++  java
  • 迭代函数与迭代函数的实现

    前言

    说到迭代方法,最先想到的是什么?forEach还是map,迭代的方法ES5提供了5种方法。

    每个方法都接收两个参数:

      1.在每一项上运行的函数

      2.运行该函数的作用域对象(影响this的值)

    传入这些方法中的函数会接收3个参数:

      1.数组项的值

      2.该项在数组的位置

      3.数组对象本身

    迭代函数执行后可能会也可能不会影响返回结果 (雾..)

    ES5提供的迭代函数:

    • forEach(): 对数组中的每一项运行给定函数,无返回值
    • every(): 对数组中的每一项运行给定函数,如果该函数每一项都返回true,则返回true
    • some(): 对数组中的每一项运行给定函数,如果该函数任意一项返回true,则返回true
    • map(): 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
    • filter(): 对数组中的每一项运行给定函数,该函数会返回true的项组成的数组

    参数说明

    let array = [1,2,3,4,5,6,7,8,9]
    array.forEach((element,index,array) => {
      console.log(`当前遍历元素${element}`);
      console.log(`当前元素位置${index}`);
      console.log(`数组本身${array}`);
    })
    
    > 当前遍历元素1
    > 当前元素位置0
    > 数组本身1,2,3,4,5,6,7,8,9
    > 当前遍历元素2
    > 当前元素位置1
    > 数组本身1,2,3,4,5,6,7,8,9
    > 当前遍历元素3
    > 当前元素位置2
    > 数组本身1,2,3,4,5,6,7,8,9

    forEach可以说是最常用的一个迭代方法了,该方法没有返回值,与for循环的效果一样。

    forEach的第二个参数,js高程上说明 是运行该函数的作用域对象,可以看一下经典的例子:

    let obj2 = {
      name: '张三',
      times:[1,2,3],
      print:function () {
        this.times.forEach(function(res) {
          console.log(this.name);
        },this)
      }
    }
    // 迭代函数内部的function默认指向windows 第二个参数调整了this指向
    obj2.print()
    // 张三
    // 张三
    // 张三

    如果这么写看不太懂的话,看箭头函数的写法一下子就能明白。

    let obj2 = {
      name: '张三',
      times:[1,2,3],
      print:function () {
        this.times.forEach(res => {
          console.log(name);
        })
      }
    }
    // 箭头函数this指向父级,所以他不需要调整this
    obj2.print()
    // 张三
    // 张三
    // 张三

    every(判断函数)

    对数组中的每一项运行给定函数,如果该函数每一项都返回true,则返回true。

    默认返回false

    var array = [1,2,3,4,5,6,7,8,9]
    var result = array.every(e => {})
    console.log(result); // 
    > false 

    全部ture才会返回true

    var array = [1,2,3,4,5,6,7,8,9]
    var result = array.every(e => {
      return e > 0
    })
    console.log(result);
    > true
     
    var array = [1,2,3,4,5,6,7,8,9]
    var result = array.every(e => {
      return e > 1
    })
    console.log(result);
    > false

    some(判断函数)

    对数组中的每一项运行给定函数,如果该函数任意一项返回true,则返回true。

    默认返回false

    var array = [1,2,3,4,5,6,7,8,9]
    var result = array.some(e => {})
    console.log(result); // 
    > false 

    全部false才会返回false

    var array = [1,2,3,4,5,6,7,8,9]
    var result = array.some(e => {
      return e > 8
    })
    console.log(result);
    > true
     
    var array = [1,2,3,4,5,6,7,8,9]
    var result = array.some(e => {
      return e > 9
    })
    console.log(result);
    > false

    以上两个都不是很常用,但是毫无疑问在特定的需求下,这个要比用forEach代码要简洁很多。

    filter(过滤函数)

    对数组中的每一项运行给定函数,该函数会返回true的项组成的数组。

    var array = [1,2,3,4,5,6,7,8,9]
    var result = array.filter(e => {
      return e>5
    })
    console.log(result);
    > [6, 7, 8, 9]

    上面的例子,array数组里面大于5的数会被过滤出来,filter函数在日常当中比较常用。

      1 //map(处理函数)
      2 //对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
      3 var array = [1,2,3,4,5,6,7,8,9]
      4 var result = array.map(e => {
      5   return e>5
      6 })
      7 console.log(result);
      8 //> [false, false, false, false, false, true, true, true, true]
      9  
     10 var array = [1,2,3,4,5,6,7,8,9]
     11 var result = array.map(e => {
     12   return e*2
     13 })
     14 console.log(result);
     15 //> [2, 4, 6, 8, 10, 12, 14, 16, 18]
     16  
     17 //forEach(迭代函数)对数组中的每一项运行给定函数,无返回值。
     18 var array = [1,2,3,4,5,6,7,8,9]
     19 var arraypush = []
     20 var result = array.forEach(e => {
     21   if (e > 5) {
     22     arraypush.push(e)
     23   }
     24 })
     25 console.log(arraypush);
     26 //> [6, 7, 8, 9]
     27 //最纯粹的迭代函数,似乎forEach是处理外部数组最好的选择。
     28 //到这里,我想起了我第一次使用filter函数的时候,我惊呆了,这函数太强大了!
     29 //如此好用的工具函数,不自己实现一遍怎么能做到完全了解。
     30 //以下函数为自己实现的,并不是源码,若有错误请指点!
     31  
     32 //实现forEach首先明显forEach是Array上的原型链上的函数所以第一件事就是创建一个原型方法:
     33 //Array.prototype.MyforEach = function (){}
     34 //forEact 第一个参数为一个匿名函数 第二个参数为this指向 所以:
     35 //Array.prototype.MyforEach = function (fn,obj){}
     36 //forEach会迭代调用它的数组所以内部肯定是循环:
     37 Array.prototype.MyforEach = function (fn,obj){
     38   let len = this.length
     39   for (let index = 0; index < len; index++) {
     40     fn(this[index],index,this)
     41   }
     42 }
     43 //但是我们还没有考虑this指向的事情,所以还需要添加一些调整this的代码:
     44 Array.prototype.MyforEach = function (fn,obj){
     45   let len = this.length
     46   if (obj !== 'undefined') {
     47     fn = fn.bind(obj)
     48   }
     49   for (let index = 0; index < len; index++) {
     50     fn(this[index],index,this)
     51   }
     52 }
     53 //运行一下试试,就用之前的例子:
     54 var array = [1,2,3,4,5,6,7,8,9]
     55 Array.prototype.MyforEach = function (fn,obj){
     56   let len = this.length
     57   if (obj !== 'undefined') {
     58     fn = fn.bind(obj)
     59   }
     60   for (let index = 0; index < len; index++) {
     61     fn(this[index],index,this)
     62   }
     63 }
     64  
     65 var obj2 = {
     66   name: '张三',
     67   times:[1,2,3],
     68   print:function () {
     69     this.times.MyforEach(function(res) {
     70       console.log(this.name);
     71     },this)
     72   }
     73 }
     74 obj2.print()
     75 //> 张三
     76 //> 张三
     77 //> 张三
     78  
     79 //实现mapmap与forEach的区别是:
     80 //1.map中如果是运算,会返回每次函数调用的新的结果组成的数组
     81 //2.map中如果是判断,会返回每次迭代结果组成的数组
     82 //所以只要在迭代函数内部创建一个数组,每次迭代都push进去,最后返回出去就好啦。
     83 Array.prototype.Mymap = function (fn,obj){
     84   var resultData = []
     85   var len = this.length
     86   if (obj !== 'undefined') {
     87     fn = fn.bind(obj)
     88   }
     89   for (let index = 0; index < len; index++) {
     90     resultData.push(fn(this[index],index,this))
     91   }
     92   return resultData
     93 }
     94 //运行一下:
     95 var array = [1,2,3,4,5,6,7,8,9,]
     96 var result = array.Mymap(e => {
     97     return e*2
     98 })
     99 console.log(result);
    100 //> [2, 4, 6, 8, 10, 12, 14, 16, 18]
    101  
    102  
    103 //实现 some everysome与every都会有一个特点 默认返回false。
    104 //不同的地方在于:
    105 //1.some要求 全部返回false返回false
    106 //2.every要求 全部返回true返回true
    107 // -- every -- 
    108 Array.prototype.Myevery = function (fn,obj) {
    109   var len = this.length
    110   if (obj !== 'undefined') {
    111     fn = fn.bind(obj)
    112   }
    113   for (let index = 0; index < len; index++) {
    114     if (fn(this[index],index,this) == undefined) { // 无返回值 默认返回false
    115       return false
    116     }else if (fn(this[index],index,this) !== true) { // 出现一个不为 true 就停止迭代 返回结果
    117       return false
    118     }
    119   }
    120   return true
    121 }
    122  
    123 // -- some -- 
    124 Array.prototype.Mysome = function (fn,obj) {
    125   var len = this.length
    126   if (obj !== 'undefined') {
    127     fn = fn.bind(obj)
    128   }
    129   for (let index = 0; index < len; index++) {
    130     if (fn(this[index],index,this) == undefined) {
    131       return false
    132     } else if (fn(this[index],index,this) !== false) {
    133       return true
    134     }
    135   }
    136   return false
    137 }
    138  
    139  
    140 //实现fliter相信到这里,你也可以直接实现一个fliter函数了,仅仅是多添加一个数组。
    141 Array.prototype.Myfilter = function (fn, obj) {
    142   let resultData = []
    143   var len = this.length
    144   if (obj !== 'undefined') {
    145     fn = fn.bind(obj)
    146   }
    147   for (let index = 0; index < len; index++) {
    148     if (fn(this[index],index,this) === true) {
    149       resultData.push(this[index]) // 注意不是push函数结果
    150     }
    151   }
    152   return resultData
    153 }
    154  
    155 // -- 运行 -- 
    156  
    157 var array = [1,2,3,4,5,6,7,8,9]
    158 var result = array.Myfilter(e => {
    159   return e>5
    160 })
    161 console.log(result);
    162 //>  [6, 7, 8, 9]
    163 //perfect! :stuck_out_tongue_closed_eyes:
    164 //原来很多东西,并没有想象的那么复杂。

    * 原文地址:https://juejin.im/post/5c331657e51d4551e325d6b4

  • 相关阅读:
    Eclipse 读取config目录下文件
    cakephp 中Console / Shell 有什么优点?
    cakephp中使用 find('count')方法
    [转]using components in Cakephp 2+ Shell
    [转]Git for windows 下vim解决中文乱码的有关问题
    在Foxmail中添加阿里云企业邮箱账号
    Cakephp在Controller中显示sql语句
    java线程的基本概念
    mysql varchar到底能存多少字符。
    mysql 联合索引匹配原则
  • 原文地址:https://www.cnblogs.com/fei-H/p/11358483.html
Copyright © 2011-2022 走看看