模拟实现数组的核心方法

这是我参与更文挑战的第26天,活动详情查看: 更文挑战

前言

之前写了两篇关于数组的文章:

  1. 模拟实现数组新增的东西

  2. 数组遍历方式大汇总

本篇文章将模拟实现数组的核心方法,算是对上面两篇文章的补充,也是对数组这块知识最后的补充!

模拟实现核心方法

为了方便记忆,我将它们分为两类:

image.png

下面开始一个一个实现

可改变原数组的方法

1. push()

作用

用于在数组最后添加一个或多个元素,并返回添加新元素后的数组长度

模拟实现

Array.prototype._push = function(){
    for(var i=0;i<arguments.length;i++){
        this[this.length] = arguments[i];
    }
    return this.length;
}
//test code
var arr = [1,2,3];
console.log(arr._push(4,5));//5
console.log(arr)//[1,2,3,4,5]
复制代码

2. pop()

作用

用于删除数组最后一位元素,并返回该元素;相当于剪切

模拟实现

Array.prototype._pop = function () {
    if (this.length) {
        var result = this[this.length - 1]
        delete this[this.length];
        this.length--;
        return result;
    }
}
//test code
var arr = [1,2,3,4]
console.log(arr._pop());//4
console.log(arr);//[1,2,3]
console.log(arr.length);//3

复制代码

3. unshift()

作用

用于在数组的开头添加一个或多个元素,并返回添加新元素后的数组长度

模拟实现

Array.prototype._unshift = function () {    
    //将数组本来元素移到后面去
    for (var i = this.length - 1; i >= 0; i--) {
        this[i + arguments.length] = this[i];
    }
    //将要添加的元素,一个一个添加进腾出来的空位上
    for (var j = 0; j < arguments.length; j++) {
        this[j] = arguments[j];
    }
    return this.length;
}
var arr = [1, 2, 3]
console.log(arr._unshift('a', 'b', 'c'));//6
console.log(arr);//['a','b','c',1,2,3]
console.log(arr.length);//6
复制代码

4. shift()

作用

用于删除数组的第一个元素,并返回该元素。跟pop一样相当于剪切

模拟实现

Array.prototype._shift=function(){
    var res =  this[0];
    //让前一位等于后一位,将第一位覆盖掉。
    for(var index in this){
        this[index-1] = this[index]
    }
    return res;
}
//test code
var arr = [1, 2, 3]
console.log(arr.shift());//1
console.log(arr);//[2,3]
console.log(arr.length);//2
复制代码

5. reverse()

作用

用于颠倒数组中元素的顺序,返回改变后的数组

模拟实现

Array.prototype._reverse = function () {
    var left = 0;//存储左边第一个位置
    var right = this.length - 1;//存储右边最后一个位置
    while (left < right) {//停止进行的条件
        var temp = this[left];//利用一个中间变量来交换位置
        this[left] = this[right];
        this[right] = temp;
        left++;
        right--;

    }
}
var arr = [1, 2, 3, 4, 5, 6, 7]
console.log(arr._reverse());//undefined
console.log(arr);// [7, 6, 5, 4, 3, 2, 1]

复制代码

6. splice()

作用

截取并添加,返回被截取部分;添加在切口处添加,添加的新数据在原数组上

格式如下:arr.splice(从第几位开始, 截取的长度, 在切口处添加的数据1, 数据2, …);

默认从第o为开始,截取到数组.length-1位

模拟实现

Array.prototype._splice = function (start = 0, leng = this.length, ...data) {
    if (this.length) {
        let res = []
        let j = 0
        // 将要返回的数据找到,并保存好res
        for (let i = start; j < leng; i++, j++) {
            res.push(this[i]);
        }
        // 在缺口处添加数据
        // 找到前半段
        let beforeArr = []
        for (let i = 0; i < start; i++) {
            beforeArr.push(this[i]);
        }
        // 找到后半段
        let afterArr = []
        for (let i = start + leng; i < this.length; i++) {
            afterArr.push(this[i]);
        }
        // 最后当前数组变成剪切后的结果
        let newThis = [...beforeArr,...data,...afterArr]
        // this = newThis 这句报错待完善~~~~~~~~~
        // 返回剪切的数据res
        return res
    }

}
let a = [1,2,3,4,5,6,7,8]
let b = [1,2,3,4,5,6,7,8]
console.log(a.splice(1,2,'a','b'),a);
console.log(b._splice(1,2,'a','b'),b);
复制代码

7. sort()

作用

用于对数组成员进行排序,返回排好序的当前数组

模拟实现

Array.prototype._sort = function (fn) {
    // 先考虑没有fn的情况
    debugger
    let temp
    for (var i = 0; i < this.length; i++) {
        for (var j = i+1; j < this.length; j++) {
            if (this[i] > this[j]) {
                temp = this[j]
                this[j] = this[i]
                this[i] = temp;
            }
        }               
    }
    return this
}
console.log([1,2,5,1,9,3, 1].sort());//[1, 1, 1, 2, 3, 5, 9]
console.log([1,2,5,1,9,3, 1]._sort());//[1, 1, 1, 2, 3, 5, 9]

复制代码

不改变原数组的方法

1. concat()

作用

合并两个或多个数组,形成新数组,并返回新数组

模拟实现

Array.prototype._concat = function(...args){    
    // 将当前数组拷贝过去
    let res = [...this]
    for (let i = 0; i < args.length; i++) {
        // 获得到要添加的数组args[i];
        if(args[i].length){
            for (let index = 0; index < args[i].length; index++) {
                res.push(args[i][index]);                
            }
        }        
    }
    return res
}
let a = [1,2]
let b = [1,2]
console.log(a.concat(['x','y']),a);//[1, 2, "x", "y"]  [1, 2]
console.log(b._concat(['x','y']),b);//[1, 2, "x", "y"]  [1, 2]
复制代码

2. slice()

作用

用于截取数组,传递两个参数分别表示从第几位截取到第几位,返回截取部分,默认参数为从第0位开始到最后一位

模拟实现

Array.prototype._slice = function(start = 0,end=this.length){
    let res = []
    for (let i = start; i < end; i++) {
        res.push(this[i]);        
    }
    return res
}
console.log([1,2,3,4,5].slice(1,3))//[2,3]
console.log([1,2,3,4,5].slice(1,3))//[2,3]

复制代码

3. join()

作用

用于将数组元素连成一个字符串,返回该字符串。元素间通过传参作为指定分隔符分割,不传参会按照”,”连接

模拟实现

Array.prototype._join = function () {
    let res = ''
    let temp = arguments.length ? arguments[0] : ',';
    for (let i = 0; i < this.length; i++) {
        if(i<this.length-1){
            res += (this[i]+temp); 
        }else{
            res += this[i]
        }               
    }
    return res
}
console.log([1,2,3].join());//1,2,3
console.log([1,2,3]._join());//1,2,3

复制代码

4. toString()

作用

用于返回数组的字符串形式,undefined、null会被认为是空,嵌套数组不管多少层一律会被拍平

模拟实现

Array.prototype._toString=function(){
    let res = ''
    for (let i = 0; i < this.length; i++) {
        if(Array.isArray(this[i])){
            _toString(this[i])
        }else{
            if(i<this.length-1){
                res +=this[i].toString()+','
            }else{
                res +=this[i].toString()
            }
        }        
    }
    return res
}
console.log(['a','b','c'].toString());//a,b,c
console.log(['a','b','c']._toString());//a,b,c
复制代码

END

以上就是数组的核心方法的模拟实现!

真正的实现可能跟我写的不一样,不过没有关系,我们只要熟知这些方法具体干了什么,也就达到了这次学习的目的了!

如有疑问或建议,希望可以留言告知,感谢你!!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享