【JavaScript知识碎片】通过数组对象的原型对象模拟数组方法

75 阅读4分钟

Hello,各位大佬好,我是刚开始写文章的予光,想记录一下自己的学习与成长过程,希望和大家一起共同学习和进步。

1709082527410.jpg

1.数组简介

数组是一种有序的数据集合,它可以存储多个值,并根据索引访问和操作这些值。在 JavaScript 中,数组是一种动态类型的数据结构,可以容纳任意类型的数据,包括基本类型和对象。

2.数据方法API

一些常用的数组API:

添加和删除数组

  • push():在数组末尾添加一个或多个元素,并返回新数组的长度。
  • pop():移除并返回数组的最后一个元素。
  • shift():移除并返回数组的第一个元素
  • unshift():在数组开头添加一个或多个元素,并返回新数组的长度。
  • splice():从指定位置添加或删除元素。

修改和访问元素

  • slice():返回数组的一部分,不改变原数组。
  • concat():将多个数组合并为一个新数组。
  • join():将数组的元素连接成一个字符串。
  • reverse():颠倒数组中元素的顺序。
  • sort():对数组元素进行排序。

遍历数组

  • forEach():对数组的每个元素执行指定的操作。
  • map():创建一个新数组,其中的元素是原始数组经过指定操作后的结果。
  • filter():创建一个新数组,其中的元素是符合指定条件的原始数组元素。
  • reduce():对数组的元素进行累加或合并操作。

数组转换和连接

  • toString():将数组转换为字符串。
  • toLocaleString():将数组转换为本地化的字符串。
  • join():将数组的元素连接成一个字符串。

数组排序和搜索

  • sort():对数组元素进行排序。
  • reverse():颠倒数组中元素的顺序。
  • indexOf():返回指定元素在数组中首次出现的索引。
  • lastIndexOf():返回指定元素在数组中最后一次出现的索引。

其他常用方法

  • isArray():检测一个值是否为数组。
  • find():返回数组中符合指定条件的第一个元素。
  • findIndex():返回数组中符合指定条件的第一个元素的索引。
  • some():检测数组中是否至少有一个元素符合指定条件。
  • every():检测数组中是否所有元素都符合指定条件。

更多详细的方法和用法请参考MDN Web Docsopen in new window。

4.实现数组API

为了更好地理解数组的方法和实现原理,尝试自己模拟实现一些数组 API 的方法。

实现添加和删除元素的方法

        // 模拟实现 push()方法
        Array.prototype.myPush = function (...elements) {
            const len = this.length
            let i = 0
            while (i < elements.length) {
                this[len + i] = elements[i]
                i++
            }
            return this.length
        }

        // 模拟实现 pop()方法
        Array.prototype.myPop = function () {
            let lastElement = this[this.length - 1]
            delete this[this.length - 1]
            this.length--
            return lastElement
        }

        // 模拟实现 unshift()方法
        Array.prototype.myUnshift = function (...elements) {
            const originalLength = this.length
            for (let i = originalLength - 1; i >= 0; i--) {
                this[i + elements.length] = this[i]
            }
            for (let i = 0; i < elements.length; i++) {
                this[i] = elements[i]
            }
            this.length = originalLength + elements.length
            return this.length
        }

        // 模拟实现 shift()方法
        Array.prototype.myShift = function () {
            if (this.length === 0) return undefined
            const firstElement = this[0]
            for (let i = 0; i < this.length - 1; i++) {
                this[i] = this[i + 1]
            }
            delete this[this.length - 1]
            this.length--
            return firstElement
        };

        // 示例使用
        const myArray = [1, 2, 3]
        console.log(myArray.myPush(4, 5)) // 输出:5
        console.log(myArray) // 输出:[1, 2, 3, 4, 5]
        console.log(myArray.myPop()) // 输出:5
        console.log(myArray) // 输出:[1, 2, 3, 4]
        console.log(myArray.myUnshift(0)) // 输出:5
        console.log(myArray) // 输出:[0, 1, 2, 3, 4]
        console.log(myArray.myShift()) // 输出:0
        console.log(myArray) // 输出:[1, 2, 3, 4]

实现修改和访问元素的方法

        // 模拟实现 splice() 方法 
        Array.prototype.mySplice = function (startIndex, deleteCount, ...elements) {
            const removedElements = []
            const len = this.length
            const deleteEndIndex = Math.min(startIndex + deleteCount, len);
            const moveCount = len - deleteEndIndex
            // 保存删除的元素
            for (let i = startIndex; i < deleteEndIndex; i++) {
                removedElements.push(this[i])
            }
            // 移动剩余元素
            for (let i = 0; i < moveCount; i++) {
                this[startIndex + deleteCount + i] = this[startIndex + deleteCount + i + moveCount]
            }
            // 插入新元素
            for (let i = 0; i < elements.length; i++) {
                this[startIndex + i] = elements[i]
            }
            // 更新长度
            this.length = len - deleteCount + elements.length;
            return removedElements
        };
        // 示例使用
        const myArray = [1, 2, 3, 4, 5]
        console.log(myArray.mySplice(2, 2, 'a', 'b')) // 输出:[3, 4]
        console.log(myArray) // 输出:[1, 2, 'a', 'b',5]

实现数组遍历的方法

        // 模拟实现 forEach() 方法 
        Array.prototype.myForEach = function (callbackFn) {
            for (let i = 0; i < this.length; i++) {
                callbackFn(this[i], i, this)
            }
        }
        // 模拟实现 map() 方法 
        Array.prototype.myMap = function (callbackFn) {
            const mappedArray = []
            for (let i = 0; i < this.length; i++) {
                mappedArray.push(callbackFn(this[i], i, this))
            }
            return mappedArray
        }
        // 示例使用 
        const myArray = [1, 2, 3]
        myArray.myForEach((value, index) => {
            console.log(`Element at index ${index} is ${value}`)
        });
        const doubledArray = myArray.myMap(value => value * 2)
        console.log(doubledArray) // 输出:[2, 4, 6]

实现数组转换和连接的方法

        // 模拟实现 toString() 方法
        Array.prototype.myToString = function () {
            let result = ''
            for (let i = 0; i < this.length; i++) {
                if (i > 0) {
                    result += ','
                }
                result += this[i]
            }
            return result
        };
        // 模拟实现 join() 方法 
        Array.prototype.myJoin = function (separator = ',') {
            let result = ''
            for (let i = 0; i < this.length; i++) {
                if (i > 0) {
                    result += separator
                }
                result += this[i]
            }
            return result
        };
        // 示例使用
        const myArray = [1, 2, 3]
        console.log(myArray.myToString()) // 输出:'1, 2, 3'
        console.log(myArray.myJoin('-')) // 输出:'1-2-3'

实现数组排序和搜索的方法

   // 模拟实现 sort() 方法 
        Array.prototype.mySort = function (compareFn) {
            const length = this.length
            for (let i = 0; i < length - 1; i++) {
                for (let j = 0; j < length - 1 - i; j++) {
                    if (compareFn(this[j], this[j + 1]) > 0) {
                        [this[j], this[j + 1]] = [this[j + 1], this[j]]
                    }
                }
            }
            return this
        };
        // 模拟实现 indexOf() 方法 
        Array.prototype.myIndexOf = function (searchElement, fromIndex = 0) {
            const length = this.length
            for (let i = Math.max(fromIndex, 0); i < length; i++) {
                if (this[i] === searchElement) {
                    return i
                }
            }
            return -1
        };
        // 示例使用 
        const myArray = [5, 2, 1, 4, 3]
        console.log(myArray.mySort()) // 输出:[1, 2, 3, 4, 5]
        console.log(myArray.myIndexOf(4)) // 输出:3

实现其他常用方法

  // 模拟实现 isArray() 方法
        Array.myIsArray = function (obj) {
            return Object.prototype.toString.call(obj) === '[object Array]'
        };
        // 模拟实现 find() 方法 
        Array.prototype.myFind = function (callbackFn) {
            for (let i = 0; i < this.length; i++) {
                if (callbackFn(this[i], i, this)) {
                    return this[i]
                }
            }
            return undefined
        };
        // 示例使用
        const myArray = [1, 2, 3, 4, 5]
        console.log(Array.myIsArray(myArray)) // 输出:true
        console.log(myArray.myFind(value => value > 3)) // 输出:4