实现数组的forEach,map,filter,some,reduce等方法

forEach() 方法对数组的每个元素执行一次给定的函数。

map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。

some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。

reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

基本的流程类似:

  1. 引用对象(this)如果是null,抛出错误
  2. 传入的第一个参数如果不是函数,抛出错误
  3. 创建当前对象,获得长度,while(k<len)循环遍历对象k++
  4. 如果下标存在于对象中if(k in obj)
  5. 回调函数(第一个参数)使用call绑定this(第二个参数),value,index,obj

区别:

forEach:没有返回值,绑定相应的this和值(value,index,obj)就行

callback.call(thisa,o[k],k,o)

Map:把第5步的结果添加到新数组中 res[k]=callback.call(thisarg,o[k],k,o)

最后返回新的数组

Filter:判断第5步的结果,为真(通过测试)则把value加入到新数组,最后返回新数组

if(callback.call(thisarg,o[k],k,o)){

                res.push(o[k])

            }

Some:判断第5步的结果,为真(通过测试)则返回布尔值

if(callback.call(thisarg,o[k],k,o)){

                return true

            }

Reduce:与前几个有些许差别,第二个参数为初值,

第1,2步骤一样,

3,判断是否有传入初值,如果传入了,接收初值

4,如果没有传入,数组中第一个非空元素为初始值,如果找不到非空的值抛出错误

5,遍历对象,如果下标存在于对象中if(k in obj),重置初值,最后返回初值,作为下一次调用回调函数的初值

 acc=callback(acc,o[k],k,o)

具体代码:

forEach:

Array.prototype.foreach1=function(callback,thisa){
    //谁调用foreach1,this就指向谁
    if(this==null){
        throw new TypeError('this is null or not defined')
    }
    //判断是否为函数
    if(typeof callback!=='function'){
        throw TypeError (callback+'is not a function')
    }
    const o=Object(this)  //当前数组
    const len=o.length>>>0   //保证转换后的值为正整数(获取数组的长度)

    let k=0
    while(k<len){
        if(k in o){  //k是下标
            //callback的this,当前元素,下标,当前数组
            //call方法中说明,如果没有传入this,则指向window
            callback.call(thisa,o[k],k,o)
        }
        k++
    }

}
let arr=[1,2]

arr.foreach1(function(item){
    console.log(item)
})

map:

Array.prototype.map1=function(callback,thisarg){
    if(this==null){
        throw TypeError('cc')
    }
    if(typeof callback!=='function'){
        throw TypeError('cc')
    }

    const o=Object(this)
    const len=o.length>>>0
    //用于接收返回值
    let res=[]
    let k=0
    while(k<len){
        if(k in o){
            res[k]=callback.call(thisarg,o[k],k,o)
        }
        k++
    }
    return res
}

filter:

Array.prototype.filter1=function(callback,thisarg){
    if(this==null){
        throw TypeError('cc')
    }
    if(typeof callback!=='function'){
        throw TypeError('cc')
    }
    const o=Object(this)
    const len=o.length>>>0
    let k=0
    let res=[]
    while(k<len){
        if(k in o){
            if(callback.call(thisarg,o[k],k,o)){
                res.push(o[k])
            }
        }
        k++
    }
    return res
}

some:

Array.prototype.filter1=function(callback,thisarg){
    if(this==null){
        throw TypeError('cc')
    }
    if(typeof callback!=='function'){
        throw TypeError('cc')
    }
    const o=Object(this)
    const len=o.length>>>0
    let k=0
    
    while(k<len){
        if(k in o){
            if(callback.call(thisarg,o[k],k,o)){
                return true
            }
        }
        k++
    }
    return false
}

reduce:

Array.prototype.reduce1=function(callback,init){
    if (this == null) {
        throw new TypeError('this is null or not defined')
    }
    if (typeof callback !== "function") {
        throw new TypeError(callback + ' is not a function')
    }
    const o=Object(this)
    const len=o.length>>>0
    let k=0
    
    let acc   //初始值
    if(arguments.length>1){
        acc=init
    }else{
        //没传入初始值,则数组中第一个非空元素为初始值
        while(k<len&& !(k in o)){
            k++
        }
        if(k>len){
            throw new TypeError('no init value')
        }
        acc=o[k++]
    }
    while(k<len){
        if(k in o){
            acc=callback(acc,o[k],k,o)
        }
        k++
    }
    return acc
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值