最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 数组常用遍历方法的实现原理

    正文概述 掘金(你不对劲_)   2020-12-27   370

    forEach

    • 遍历数组中的每一项值,方法无返回值。方法接收两个参数,第一个参数必选是一个回调函数,函数接收三个参数,第一个为遍历数组中的值,第二个为遍历数组中的索引,第三个为遍历数组本身;第二个参数可选,改变第一个参数内部的this指向。

      var data = [
        {name: 'zhangsan', age: 23},
        {name: 'lisi', age: 24},
        {name: 'wangwu', age: 25}
      ]
          
      data.forEach(function(item, index, arr){
        // 三个参数一般不会全部传入,看你具体的需求,这里的目的是学习/回顾,所以我全写了。
        console.log(item);
        console.log(index);
        console.log(arr);
        console.log(this);
      }, {name: 'zhaoliu'});
          
      // 重写forEach
      Array.prototype.myForEach = function (fn) {
        var arr = this, // 保存调用该函数的数组
            len = arr.length,
            arg = arguments[1] || window; // 第二个参数是改变第一个参数内部的 this 指向,如果没传就是默认指向window
          
        for(var i = 0; i < len; i++){
          fn.apply(arg, [arr[i], i, arr]);
        }
      }
      

    filter

    • 筛选过滤数组,和forEach的用法相同,但是有返回值,会将满足回调函数条件的成员组成一个新的数组返回。

      var data = [
        {name: 'zhangsan', age: 23},
        {name: 'lisi', age: 24},
        {name: 'wangwu', age: 25}
      ]
          
      var res = data.filter(function(item, index, arr){
        return item.age > 23;
      })
      console.log(res); // -> [{name: 'lisi', age: 24}, {name: 'wangwu', age: 25}]
          
      // 重写 filter
      Array.prototype.myFilter = function (fn) {
        var arr = this,
            len = arr.length,
            arg = arguments[1] || window,
            res = []; // 因为要有返回值,且返回值是一个数组
            
        for(var i = 0; i < len; i++){
          // 如果返回结果为真 就添加到 res 中,否则什么也不干
          fn.apply(arg, [arr[i], i, arr]) ? res.push(arr[i]) : '';
        }
        return res; // 最后将数组返回
      }
      
    • 注意:原始的filter返回的数组和原始数组也都只是经过浅拷贝,就是数组中的值如果是引用类型的值,修改返回后的数组,原始数组也会改变。 解决方法:在我们自己写的函数往返回的数组添加之前,进行一次深拷贝。

    map

    • 用法类似,也是返回一个新数组,数组中的成员为原始数组成员经过回调函数处理后的值,新数组与原始数组也是映射的关系(如果为引用类型值,修改新数组,原始数组也会改变)。

      var data = [
        {name: 'zhangsan', age: 23},
        {name: 'lisi', age: 24}
      ]
          
      var res = data.map(function (item, index, arr) {
        item.name = 'wangwu';
        return item;
      })
      console.log(res, data);
          
      // 重写map
      Array.prototype.myMap = function (fn) {
        var arr = this,
            len = arr.length,
            arg = arguments[1] || window,
            res = [];
          
        for(var i = 0; i < len; i++) {
          // 打断映射关系,可以在这里对原始数组的每一项进行深克隆
          res.push(fn.apply(arg, [arr[i], i, arr]));
        }
        return res;
      }
      

    every

    • 返回一个布尔值,数组成员都复合回调函数的条件才返回true,否则返回false

      var data = [14, 18, 22];
      var res = data.every(function (item, index, arr) {
        return item > 18;
      })
      console.log(res); // -> false
          
      // 重写 every
      Array.prototype.myEvery = function (fn) {
        var arr = this,
            len = arr.length,
            arg = arguments[1] || window,
            res = true;
            
        for(var i = 0; i < len; i++){
          // 如果有一个不符合条件,就停止循环直接返回false
          if(!fn.apply(arg, [arr[i], i, arr])){
            res = false;
            break;
          }
        }
        return res;
      }
      

    some

    • 也是返回一个布尔值,条件为只要有一个成员满足,就返回true,否则返回false

      var data = [14, 18, 22];
      var res = data.some(function (item, index, arr) {
        return item > 18;
      })
      console.log(res); // -> true
          
      // 重写some
      Array.prototype.mySome = function (fn) {
        var arr = this,
            len = arr.length,
            arg = arguments[1] || window,
            res = false;
            
        for(var i = 0; i < len; i++){
          // 如果有一个符合条件,就停止循环直接返回true
          if(fn.apply(arg, [arr[i], i, arr])){
            res = true;
            break;
          }
        }
        return res;
      }
      

    reduce

    • 归纳函数,方法接收两个参数,第一个参数是回调函数,回调有四个参数,第一个previousValue(上一次回调返回的值,或是提供的初始值(initialValue)),第二个currentValue(当前被处理的成员),第三个index(当前成员的索引),第四个array(调用方法的数组本身);方法的第二个参数 initialValue (作为第一回调函数的第一个参数)。返回值就是previousValue / initialValue。

      var data = [
        {name: 'zhangsan', age: 13},
        {name: 'lisi', age: 16},
        {name: 'wangwu', age: 18},
        {name: 'zhaoliu', age: 22}
      ]
          
      var res = data.reduce(function (pre, item, index, arr) {
        if(item.age >= 18){
          pre.push(item);
        }
        return pre;
      },[]);
      console.log(res);
          
      // 重写 reduce 我们给他附加一个功能,如果传入第三个参数,就改变回调内部的this指向
      Array.prototype.myReduce = function (fn, initialValue) {
        var arr = this,
            len = arr.length,
            arg = arguments[2] || window, // 附加功能的参数
            item; 
            
        for(var i = 0; i < len; i++){
          item = arr[i];
          initialValue = fn.apply(arg, [initialValue, item, i, arr]);
        }
        return initialValue;
      }
      

    起源地下载网 » 数组常用遍历方法的实现原理

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元