ES5中map、filter、forEach、reduce解析

2,193 阅读3分钟

map

用途

  • 对数组进行映射(对原数组中的每一项做某种操作,操作的结果保存在新数组中返回)
  • 不会修改原数组

参数

  • map(callback,_this);//(回调函数,this指向)
  • callback(item,index,array)//(数组中每一项,每一项下标,数组)

基本使用

var arr = [1,2,3,4]
var newArr = arr.map(function(){
    //此时this指向是document
    console.log(this);
    //若没有第二个参数,this的指向是Window
},document)

var arr = [1,2,3,4]
var newArr = arr.map(function(){
    return item*2;
})
console.log(arr,newArr);

封装

Array.prototype.mapNew = function(callback){
    //1.边界值判断,判断用户传入的是不是一个回调函数
    if(typeof callback !== 'function'){
        throw new Error(callback+'is not a function');   
    }
    
    //2.获取是谁调用的本方法,this指的就是调用map这个函数的数组
    var arr =this;
    
    //3.因为不会修改原数组,所以要创建一个new数组
    var newArr = [];
    
    //4.如果有this指向传入,处理this指向
    var _this = arguments[1] || window;
    
    //5.做相关遍历
    for(var i=0;i<arr.length;i++){
        //6.执行callback方法(修改this指向,item,index,array)
        newArr.push(callback.call(_this,arr[i],i,arr));
    }
    return newArr;
}

测试

var arr = [1,2,3,4];
var newArr = arr.mapNew(function(item){
    return item*2
})
console.log(arr,newArr);

filter

用途

  • 数据筛选
  • 将所有符合条件的元素放到新数组中返回;如果没有符合条件的元素,则返回一个空数组。

参数

  • filter(callback,_this);
  • callback(item,index,array)

基本使用

var newArr = arr.filter(function(){
    //  this指向document
    console.log(this)
},document)
var arr = [1,2,3,4];
var newArr = arr.filter(function(){
    return item%2 == 0
},document)
console.log(newArr)

封装

Array.prototype.filterNew = function(callback){
    //1.边界值判断,判断用户传入的是不是一个回调函数
    if(typeof callback !== 'function'){
        throw new Error(callback+'is not a function');   
    }
    var arr = this;
    var newArr = [];
    var _this = argument[1] || window;
    for(var i=0;i<arr.length;i++){
        //如果callback执行结果返回值是真
        if(callback.call(_this,arr[i],i,arr){
            newArr.push(arr[i]);
        }
    }
    return newArr;
}

测试

var arr = [1,2,3,4];
var newArr = arr.filterNew(function(item){
    console.log(this);
    return item%2 ===0;
})
console.log(arr,newArr);

forEach

特点

  • 没有返回值

基本使用

var arr = [1,2,3,4];
var newArr = [];
arr.forEach(function(item,index,arr){
    console.log(this);
    newArr.push(item*=2);
},document)
console.log(newArr);

封装

Array.prototype.forEachNew = function(callback){
    if(typeof callback !== 'function'){
        throw new Error(callback+'is not function');
    }
    //获取谁去调用forEach了
    var arr = this;
    var _this = arguments[1] || window;

    for(var i=0;i<arr.length;i++){
        callback.call(_this,arr[i],i,arr);
    }
}

reduce

特点

  • 是一个累加器

参数

  • reduce(callback,initValue);(回调函数;初始值)
  • callback(prev,current,index,array)(初始值, 或者计算结束后的返回值;当前元素;当前元素索引;当前数组)

基本使用

//查找数组中的最大值
var n = arr.reduce(function(pre,curr){
    return Math.max(pre,curr)
})
console.log(n);
//扁平化数组
var arr = [[1,2],[3,4],[5,6,[7,8]]];

function mapArr(arr){
    return arr.reduce(function(pre,curr){
        return pre.concat(Array.isArray(curr)?mapArr(curr):curr);
    },[])
}

console.log(mapArr(arr));
//判断字符串中每个字符出现的次数
 var str = "aabbcc";
 var obj = str.split('').reduce(function(pre,cur){
     if(pre[cur]){
         pre[cur]++;
     }else{
         pre[cur] = 1;
     }

     return pre;
 },{})
//将url地址中的query参数提取出来
var url = "http://www.baidu.com?username=alley&age=18";

var obj = url.substr(url.indexOf("?")+1).split("&").reduce(function(pre,cur){
     var key = cur.split("=")[0];
     var val = cur.split("=")[1];
     pre[key] = val;
     return pre;
},{})

封装

Array.prototype.reduceAlley = function(callback,initVal){
    if(typeof callback !== 'function'){
        throw new Error(callback+'is not function');
    }

    var arr = this;
    //判断初始值是否传入了 默认为false
    var isInitVal = false;
    var prev;//存储上一次的值

    //判断初始值是否存在
    if(initVal){
        //如果存在将状态值改为true
        isInitVal = true;
        //同时将初始值复制给上一次的结果
        prev = initVal;
    }

    for(var i=0;i<arr.length;i++){
        //判断初始值是否存在
        if(isInitVal){
            //执行callback将上一次的结果赋值给prev
            prev = callback(prev,arr[i],i,arr);
        }else{
            //如果不存在的时候讲数组中的第一个值赋值给prev 同时将状态值改为true
            prev = arr[i];
            isInitVal = true;
        }
    }

    return prev;
}