JS数组原型中方法实现,forEach,map,filter,some,reduce

forEach,map,filter,some,reduce五个方法都是不改变原数组的方法。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>实现数组原型方法</title>
</head>
<body>

    <script>

        //实现forEach方法。forEach方法对数组中的每个元素执行一次给定的函数,不会直接改变调用它的对象,但是回调函数可能会改变它
        Array.prototype.forEach2=function(callBack,thisArg){
            if (this === null) {
                throw new TypeError("this is null or not defined")
            }
            //typeof 可以区分基本数据类型number,string,undefined,boolean,bigint,Symbol,function,object
            if (typeof callBack !== "function"){
                throw new TypeError(callBack+" is not a function")
            }
            let o=Object(this)
            //无符号位移操作符在位移前做了两种转换,第一将不是number类型的数据转换为number,第二将number转换为无符号的32位数据,也就是Unit32类型。
            //x >>> 0本质上就是保证x有意义(为数字类型),且为正整数,在有效的数组范围内(0 ~ 0xFFFFFFFF),且在无意义的情况下缺省值为0
            let len=o.length>>>0;
            let k=0;
            while (k<len){
                if (k in o){
                    callBack.call(thisArg,o[k],k,o)
                }
                k++;
            }
        }

        //实现map方法。map方法创建一个新数组,结果是该数组中每个元素调用一次函数后的返回值
        let arr=[1,2,3]

        Array.prototype.map2 = function (callback,thisArg) {
            if (this === null){
                throw new TypeError('this is null or not defined')
            }
            if (typeof callback !== "function"){
                throw  new TypeError(`${callback} is not a function`)
            }
            let o = Object(this)
            let len = o.length>>>0;
            let k=0;
            let narr=[];
            while (k<len){
                if (k in o){
                    narr[k]=callback.call(thisArg,o[k],k,o)
                }
                k++;
            }
            return narr;
        }
        let mapArr=arr.map(x=>x*2)
        console.log(mapArr)
        console.log(arr.map2(x=>x*2))

        //filter方法的实现。filter方法创建一个新数组,包含数组中所有通过所提供函数的元素
        Array.prototype.filter2 = function (callback,thisArg) {
            if (this === null){
                throw new TypeError('this is null or not defined')
            }
            if (typeof callback !== "function"){
                throw new TypeError(`${callback} is not a function`)
            }
            let o=Object(this)
            let len=o.length>>>0
            let k=0, res = [];
            while (k<len){
                if (k in o){
                    if (callback.call(thisArg,o[k],k,o)){
                        res.push(o[k])
                    }
                }
                k++;
            }
            return res;
        }
        let arr2=[1,1,2,2,3,1,5]
       let arrf = arr2.filter2(x=>x>2)
        let arrff=arr2.filter(x=>x>2)
        console.log(arrf)
        console.log(arrff)

        //实现数组的some方法。some方法测试数组中是不是至少有一个元素通过了提供的函数的测试。返回boolean类型,空数组测试返回false
        Array.prototype.some2 = function (callback,thisArg) {
            if (this === null){
                throw new TypeError('this is null or not defined');
            }
            if (typeof callback !== "function"){
                throw new TypeError(`${callback} is not a function`)
            }
            let o =Object(this)
            let len = o.length>>>0
            let k=0;
            while (k<len){
                if (callback.call(thisArg,o[k],k,o)){
                    return true;
                }
                k++;
            }
            return false
        }

        console.log(arr2.some2(x => x>10));

        //实现数组的reduce方法。reduce方法对数组中的每个元素执行给定的reducer函数,将其结果汇总为单个返回值
        Array.prototype.reduce2 = function (callback,initialValue) {
            if (this === null){
                throw new TypeError('this is null or not defined')
            }
            if (typeof callback!=="function"){
                throw new TypeError(`${callback} is not a function`)
            }
            let o =Object(this)
            let len = o.length>>>0
            let k=0, res;

            if (arguments.length>1){
                res=initialValue
            }else {
                //没传入初始值的时候,取数组中第一个非empty的值为初始值
                while (k<len && !(k in o)){
                    k++;
                }
                if (k>len){
                    throw new TypeError('Reduce of empty array with no initial value')
                }
                res=o[k++];
            }
            while (k<len){
                if (k in o){
                    res=callback(res,o[k],k,o)
                }
                k++;
            }
            return res;
        }
        console.log(arr.reduce2(function (acc,currentV) {
            return acc+currentV;
        }));
        console.log(arr.reduce(function (acc,currentV) {
            return acc+currentV;
        }));

    </script>
</body>
</html>

总结,虽然这些原型方法已经内置,不需要自己实现,但是手写这些方法的意义可能在于更加了解这些方法。
1. forEach方法对数组中每个元素执行回调函数,该方法不会直接改变原数组,但是原数组是否会被改变取决于回调函数是否改变原数组
2. map方法对数组中每个元素执行会回调函数,返回由每个元素执行回调函数的结果组成的新数组(不改变原数组)。
3. filter方法对数组中的每个元素执行回调函数,返回 由 数组中 通过了回调函数(即 使得回调函数返回true)的 元素组成的数组,不改变原数组
4. some方法对数组中的元素执行回调函数,返回布尔值,表示数组中是否存在元素 通过了回调函数(即 使得回调函数返回true),不改变原数组
5. reduce方法 MDN中是这么说的 “对数组中每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值” 。我不太理解,不改变原数组

其他,
1. typeof 可以区分基本数据类型number,string,undefined,boolean,bigint,Symbol,function,object
2. 无符号位移操作符在位移前做了两种转换,第一将不是number类型的数据转换为number,第二将number转换为无符号的32位数据,也就是Unit32类型。
x >>> 0本质上就是保证x有意义(为数字类型),且为正整数,在有效的数组范围内(0 ~ 0xFFFFFFFF),且在无意义的情况下缺省值为0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值