最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 数组拓展方法(二):every、some、reduce

    正文概述 掘金(我会接网线)   2021-01-04   404

    一. 高阶函数和回调函数

    高阶函数: function(fn) 括号里面有函数类型的参数 或者 返回的值是一个函数

         //
          function every(fn){
              fn(); //当一个函数执行的时候,它的参数是一个函数,执行时或者执行后,这个函数又执行了, 这个函数就是原函数的回调函数
             //所以回调函数属于高阶函数?
          }
    //
    

    回调函数: 把一段可执行的代码像参数传递那样传给其他代码,而这段代码会在某个时刻被调用执行,这就叫做回调。如果代码立即被执行就称为同步回调,如果在之后晚点的某个时间再执行,则称之为异步回调。

    疑问

    回调函数属于高阶函数范畴?

    二. every: 判断数组元素有无

    1.every也是原型链上的方法:Array.prototype.every
    2.every()语句中,如果有一个不满足条件就停止遍历,条件就是return后面的表达式

    var data = [{'name':'0', 'age':'18'}, {'name':'1', 'age':'28'}, {'name':'2', 'age':'28'} ]
    var res = data.every(function(elem, index, arr){
        console.log(elem);     // 仅输出 {'name':'0', 'age':'18'}, {'name':'1', 'age':'28'}
        // 因为到第二个就return false了
        return elem.name == '0'
        console.log(elem);  //不会输出, 他会一步步遍历,到return 就戛然而止,不管return后面表达式是否正确,如果正确就遍历下一句,如果不正确就直接结束遍历, 
        //所以说不管return的表达式正确与否,其后面的所有语句都不会执行,正确了就再次遍历,不正确就结束遍历 
    })
    

    所以说不管return的表达式正确与否,其后面的所有语句都不会执行,正确了就再次遍历,不正确就结束遍历

    1. every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。

       var data = [{ 'name': '0', 'age': '18' }, { 'name': '1', 'age': '28' }, { 'name': '2', 'age': '28' }]
       var res = data.every(function (elem, index, arr) {
           // 因为到第二个就return false了
           return elem.name == '0'
       })
       console.log(res); //输出false
      

    every的重写

     Array.prototype.myEvery = function (fn) {
                var arr = this, //data中的数据
                    len = arr.length,
                    args2 = arguments[1] || window,
                    res = true;
    
                for (var i = 0; i < len; i++) {
                    if (!fn.apply(args2, [arr[i], i, arr])) {
                        res = false;
                        break;
                    }
                }
                return res;
            }
    
            var data = [ { name: '1', age: '28' }, { name: '2', age: '28' }];
            var res2 = data.myEvery(function (elem, index, array) {
                console.log(elem);
                return elem.name == '1' //判断data的数据, 如果==0 只会输出data的第一项, ==1输出两项 ,因为判断语句在log之后,总会输出一句
            }, { name: 'jack' })    
            //所以说every()括号内配合  return elem.xx == 'xx' 使用
            //return比较的是data中的值,那此句中argus2有什么用?
    

    所以说every()括号内配合 return elem.xx == 'xx' 使用,比较data中的数据
    但是argus2的作用是什么? 知道特性就好,以后箭头函数等会有用

    三. some

    其功能和every差不多,也是判断数组有无此元素
    唯一的区别就是: 如果有一个满足条件就停止遍历,条件是return后面的表达式

    通俗的讲: some 遇到正确的就停止, 遇到不正确的就一直循环下去,直至找到正确的
    而every 第一项不是正确的就会停止遍历,第一项正确就会继续遍历

    some重写

            Array.prototype.mySome = function (fn) {
                var arr = this, //data中的数据
                    len = arr.length,
                    args2 = arguments[1] || window,
                    res = false;
    
                for (var i = 0; i < len; i++) {
                    if (fn.apply(args2, [arr[i], i, arr])) {
                        res = true;
                        break;
                    }
                }
                return res;
            }
    
            var data = [ { name: '1', age: '28' }, { name: '2', age: '28' }, { name: '23', age: '28' }];
            var res2 = data.mySome(function (elem, index, array) {
                console.log(elem);
                return elem.name == '0' //输出{ name: '1', age: '28' }, { name: '2', age: '28' }, { name: '23', age: '28' }
            }, { name: 'jack' })    
       //遇到正确的就停止,遇到不正确的就一直循环下去,直至找到正确的
    

    四. reduce: 完成数据归纳

    返回一个新的数组,把符合条件的值放入新数组中
    reduce的第二个参数必须填

     var data = [ { name: '1', age: '28' }, { name: '2', age: '28' }, { name: '23', age: '28' }];
    var initialValue = [];
    var  nArr = data.reduce(function(prev, elem, index, arr){ //将prev与其他三项分开来看
       console.log(prev === initialValue);// 返回true,所以prev和initialValue是一个东西
        return prev; //必须return prev; 才会有值, 不然会输出3次undefined (次数为数组中元素的个数,即遍历的次数)
    
    }, initialValue)
    

    1.prev和initialValue是一个东西, prev的值从initialValue中获取, 所以第二个参数必须填
    2.必须return才会有值,不然之后的返回会几次false(次数为数组中元素的个数 - 1,因为第一次返回true)

       var data = [{ name: '1', age: '28' }, { name: '2', age: '28' }, { name: '23', age: '28' }];
       var initialValue = [];
       var nArr = data.reduce(function (prev, elem, index, arr) { //将prev与其他三项分开来看
           prev.push(elem.name); // 每执行data.reduce 的时候都会操作一遍prev.push();
           console.log(prev); //输出["1"] 、  ["1", "2"]、 ["1", "2", "23"]
           return prev;
    
       }, initialValue)
    
    

    每执行data.reduce 的时候 都会操作一遍prev.push();
    reduce的本质其实也是遍历, 会执行一次次里面的语句

      var data = [{ name: '1', age: '28' }, { name: '2', age: '28' }, { name: '23', age: '28' }];
       var initialValue = [];
       var nArr = data.reduce(function (prev, elem, index, arr) { //将prev与其他三项分开来看
         
          if(elem.name === '1'){
              prev.push(elem);
           
          }
           return prev; //返回给新数组nArr
    
       }, initialValue)
      console.log(nArr); //输出{name: "1", age: "28"}
    

    所以说reduce 和 filter 的作用是一样的,但是方法不同: reduce是用归纳的方式来做的,而filter是过滤
    过滤: 返回布尔值是true就返回, 不是就扔掉
    归纳: 在我的条件范围之内,往一个新容器里面放值(并不是原来的那个容器) 即将符合条件的全部放入新的容器中

      var data = [{ name: '1', age: '28' }, { name: '2', age: '28' }, { name: '23', age: '28' }];
       var initialValue = [];
       var nArr = data.reduceRight(function (prev, elem, index, arr) { //将prev与其他三项分开来看
              prev.push(elem);
           //    console.log(elem);
           return prev;
    
       }, initialValue)
       console.log(nArr); //输出: {name: "23", age: "28"} 、{name: "2", age: "28"}、{name: "1", age: "28"}
       
    

    所以说reduceRight 和 reduce 唯一的不同就是返回结果是倒着来的 reduceRight就是倒序列

    总结

    所有的数组拓展方法本质都是 遍历、循环
    reduce是从0开始遍历,reduceRight是从 长度(data.length-1) 开始遍历

    reduce 实战

    将cookie数据的" name= 1; name2= 2 ; name3= 23 " 形式改为对象的形式

        
    var cookieData =  " name= 1;  name2= 2 ;  name3= 23 " 
    cookieArr = cookieData.split(";");
    // console.log(cookieArr); //数组,输出 [ name= 1", "  name2= 2 ", "  name3= 23 " ]
    
    var nArr = cookieArr.reduce(function(prev, elem){
        var item = elem.split('=');
           console.log(item); //返回三个数组
        // [" name", " 1"]     ["  name2", " 2 "]   ["  name3", " 23 "]
        
         prev [item[0]] = item[1];
         return prev;
    }, {})                //因为prev为空对象,所以nArr返回一个对象
    console.log(nArr); 
    //输出{" name": " 1", "  name2": " 2 ", "  name3": " 23 "}
    

    reduce一次次遍历,把他们分隔开:[" name", " 1"] [" name2", " 2 "] [" name3", " 23 "]
    同时 prev [item[0]] = item[1]: 因为prev为一个对象,它把数组的第0项变为了键名,第一项变为键值,
    所以才会呈现 name : 1 的形式

    reduce的重写

    
       Array.prototype.myReduce = function (fn, init) {
           var arr = this,
               len = arr.length,
               args2 = arguments[2] || window;  //对应init的下标
    
    
           for (var i = 0; i < len; i++) {
               init = fn.apply(args2, [init, arr[i], i, arr]);
           }
           return init;
       }
    
    
       var cookieData = " name= 1;  name2= 2 ;  name3= 23 "
       cookieArr = cookieData.split(";");
       var nArr = cookieArr.myReduce(function (prev, elem) {
           var item = elem.split('=');
           // console.log(item); //返回三个数组
           prev[item[0]] = item[1];
           return prev;
       }, {})
       console.log(nArr);
    

    以上输出{" name": " 1", " name2": " 2 ", " name3": " 23 "}
    1. args2 = arguments[2] || window; 是因为上面的参数有两个:第二个参数是init, 第三个参数才是{}
    2. init = fn.apply(args2, [init, arr[i], i, arr]); 将 function 中返回的值 全部放入第二个参数 { } 中, 返回第二个参数

    reduceRight重写

    唯一的不同就是for循环里面

           for (var i = len - 1; i >= 0; i--) {
                init = fn.apply(args2, [init, arr[i], i, arr]);
            }
            return init;
        }
    

    五. 难点

    elem是调用数组中的元素,和this指向无关,所以不可能是第二个参数的数组元素, 此问题困扰了很久,最近才整明白


    下载网 » 数组拓展方法(二):every、some、reduce

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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