js中flat方法的实现原理

Array.prototype.flat(),将多维数组降维

		let arr = [1, [2, 3, [4, 5, [12, 3, "zs"], 7, [8, 9, [10, 11, [1, 2, [3, 4]]]]]]];
		console.log(arr.flat(Infinity));//[1, 2, 3, 4, 5, 12, 3, "zs", 7, 8, 9, 10, 11, 1, 2, 3, 4]

自定义flat的步骤

1、首先进行类型判断,需要判断当前调用方法的this是否为一个数组,若不是数组则返回undefined,Array下有一个isArray的方法可以检测是否为一个数组,下面我提供一种万能的类型检测方法

		//万能的类型检测方法
        const checkType = (arr) => {
            return Object.prototype.toString.call(arr).slice(8, -1);
        }

2、遍历数组,并判断内部的子元素是否也是数组,如果是数组则继续拆(使用到递归和闭包),若不是则直接放入预先创建的新数组

		let arr = [1, [2, 3, [4, 5, [12, 3, "zs"], 7, [8, 9, [10, 11, [1, 2, [3, 4]]]]]]];

        //万能的类型检测方法
        const checkType = (arr) => {
            return Object.prototype.toString.call(arr).slice(8, -1);
        }
        //自定义flat方法,注意:不可以使用箭头函数,使用后内部的this会指向window
        Array.prototype.myFlat = function (num) {
            //判断第一层数组的类型
            let type = checkType(this);
            //创建一个新数组,用于保存拆分后的数组
            let result = [];
            //若当前对象非数组则返回undefined
            if (!Object.is(type, "Array")) {
                return;
            }
            //遍历所有子元素并判断类型,若为数组则继续递归,若不为数组则直接加入新数组
            this.forEach((item) => {
                let cellType = checkType(item);
                if (Object.is(cellType, "Array")) {
                    //形参num,表示当前需要拆分多少层数组,传入Infinity则将多维直接降为一维
                    num--;
                    if (num < 0) {
                        let newArr = result.push(item);
                        return newArr;
                    }
                    //使用三点运算符解构,递归函数返回的数组,并加入新数组
                    result.push(...item.myFlat(num));
                } else {
                    result.push(item);
                }
            })
            return result;
        }
        console.time();

        console.log(arr.flat(Infinity)); //[1, 2, 3, 4, 5, 12, 3, "zs", 7, 8, 9, 10, 11, 1, 2, 3, 4];

        console.log(arr.myFlat(Infinity)); //[1, 2, 3, 4, 5, 12, 3, "zs", 7, 8, 9, 10, 11, 1, 2, 3, 4];
        //自定义方法和自带的flat返回结果一致!!!!
        console.timeEnd();
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值