使用 for 语法模拟实现 js 数组的部分内置迭代方法

入行前端也已经快两年了,惭愧的是最近才开始一刷大名鼎鼎的 Professional JavaScript for Web Developers,当然,相信对于大伙,此书的中文译作《JavaScript高级程序设计》才算得上如雷贯耳。两年时间并不算短,在百度和各方技术博主的加持下,有了不少 JavaScript 的知识储备,但这些知识既多又杂、不成体系,此番看书,算是把许多零碎的知识在大脑中归档了。
私以为,检验学习成果的最好方式,就是以自己的方式复述之。对于程序员而言,批量数据的操作是颇为重要的技能,JavaScript 数组为我们提供了许多内置方法,让我们可以方便地对数据进行批量操作。今天突发奇想:用 JS 如何实现数组中的那些迭代方法?对于 JS 引擎,这些方法可能会有更加高效的实现手段,但是对我而言,貌似只能通过遍历实现了。

1. Array.prototype.reverse

reverse 方法用于将数组反序,暂时只能想到通过遍历 + 交换的方式来实现:

    Array.prototype.fakeReverse = function fakeReverse(){
        var len = this.length - 1;
        var halfLen = len / 2;
        if(!len){
            return this
        } else {
            for(var index = 0; index <= halfLen; index++){
                var item = this[index];
                this[index] = this[len - index];
                this[len - index] = item;
            }
        }
        
        return this;
    } 

2. Array.prototype.filter

filter 顾名思义,用于过滤出符合条件的数组元素,并返回一个新的数组。实现思路是创建一个新的数组,用以存储所有通过测试的元素:

    Array.prototype.fakeFilter = function fakeFilter(callback){
        if(!(callback instanceof Function)){
            throw new Error(`Uncaught TypeError: ${callback} is not a function`)
        }
        var res = [];
        for(var index = 0; index < this.length; index++){
            if(!!callback(this[index], index, this)){
                res.push(this.index);
            }
        }
        
        return res;
    }

3. Array.prototype.map

map 方法返回将当前数组各元素映射而成的新数组。实现思路同样是创建新数组来存储映射后的所有元素:

    Array.prototype.fakeMap = function fakeMap(callback){
        if(!(callback instanceof Function)){
            throw new Error(`Uncaught TypeError: ${callback} is not a function`)
        }
        var res = [];
        for(var index = 0; index < this.length; index++){
            res.push(callback(this[index], index, this));
        }
        
        return res;
    }

4. Array.prototype.reduce

reduce 方法接受两个参数:第一个参数为回调函数,第二个参数为一个“初始值”,遍历调用此回调函数处理该初始值和当前数组元素,返回的值将作为下一次处理的“初始值”:

    Array.prototype.fakeReduce = function fakeReduce(callback, initVal){
        if(!(callback instanceof Function)){
            throw new Error(`Uncaught TypeError: ${callback} is not a function`)
        }
        
        let curVal = initVal;
        
        for(var index = 0; index < this.length; index++){
            initVal = callback(initVal, this[index], index, this);
        }
        
        return initVal;
    }

5. Array.prototype.forEach

forEach 方法用于遍历数组中的每一个元素:

    Array.prototype.fakeEach = function fakeEach(callback){
        if(!(callback instanceof Function)){
            throw new Error(`Uncaught TypeError: ${callback} is not a function`)
        }
        
        for(var index = 0; index < this.length; index++){
            callback(this[index], index, this);
        }
    }

这里只写了寥寥几个数组方法,本来想把 Array.prototype.sort 也实现一个的,不过排序方法那么多,优化技巧也不少,所以打算先研究一番,有时间再专门写一篇数组排序方法的文章。以上各代码在实际项目中可能用不到,但自定义的排序方法则可能排上用场,因为针对不同场景选择正确的排序算法,可以有效提高程序的运行效率。

    原文作者:madRain
    原文地址: https://segmentfault.com/a/1190000020219377
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞