手写数组头尾增删

204 阅读1分钟

引子

对于数组的增删方法你了解多少呢,这次我们先具体讲解并实现4个小方法;

分别是: push(后添加)pop(后删除)unshift(前添加)shift(前删除)

预计阅读时长 5min

Push

功能: push() 方法将一个或多个元素添加到数组的末尾 (原地改值)

参数:{*} args 要添加的一个或多个元素

返回:数组的新长度

常规使用:

 let list = [1, 2];
 console.log(list.push( 3, "test")); // 4
 console.log(list); // [ 1, 2, 3, 'test' ]

实现

从上述代码中可以看出使用push在数组中进行添加操作十分方便快捷,实现方式也是相当的简单

实现思路:

  1. 函数形参使用剩余参数接收
  2. 判断是否传入了参数, 如果没有则返回原数组长度
  3. 循环执行args的每个元素,将元素添加到数组的末尾
  4. 在原数组队尾位置依次添加插入数组的每个元素
  5. 返回数组的新长度
 Array.prototype.push2 = function (...args) {
     if (args.length === 0) return this.length;
     for (let i = 0; i < args.length; i++) {
         this[this.length] = args[i];
     }
     return this.length;
 }
 console.log([11,22,33].push2(444,555,666)); // 6 

还有一个有趣的操作,通过apply合并两个数组:

 let list = [1, 2];
 console.log(list.push2.apply(list, [2,3,4])); // 5
 console.log(list); // [1,2,3,4,5]

原理就是通过apply指向第一个数组list再调用其内部方法添加传入的第二个数组

Pop

功能: pop() 方法从数组中删除最后一个元素,并返回该元素的值 (原地改值)

参数:

返回:被删除的元素

常规使用:

 let list = [1, "test", 3 , "test2"];
 console.log(list.pop()); // test2
 console.log(list); // [ 1, 'test', 3 ]

实现

当然 pop 实现起来也是相当简单的

实现思路:

  1. 数组为空,返回undefined
  2. 获取最后一个元素
  3. 更新数组长度
  4. 返回删除的元素
 Array.prototype.pop2 = function () {
     if (this.length === 0) return undefined; 
     let last = this[this.length - 1]; 
     this.length--;
     return last;
 }
 ​
 console.log([11, 22, 33, 44].pop2()); // 44

Shift

功能: shift 方法移除索引为 0 的元素(即第一个元素) (原地改值)

参数:

返回:被删除的元素

常规使用:

 let list = [11, 22, 33, 44];
 console.log(list.shift());
 console.log(list);

实现

实现思路:

  1. 判断数组是否为空,为空返回undefined
  2. 获取数组第一个元素
  3. 循环执行数组的每个元素,将元素向后移动一位
  4. 更新删除数组的长度
  5. 返回删除的元素
 Array.prototype.shift2 = function () {
     if (this.length == 0) return undefined; 
     let first = this[0];
     for (let i = 0; i < this.length - 1; i++) {
         this[i] = this[i + 1];
     } 
     this.length--;
     return first; 
 }
 let list = [11, 22, 33, 44];
 console.log(list.shift2());

Unshift

功能:unshift() 方法将一个或多个元素添加到数组的开头 (原地改值)

参数:{*} args : 要添加到数组开头的一个或多个元素

返回:数组长度

常规使用:

 let list =[1,2];
 console.log(list.unshift(11,22)); // 4
 console.log(list); // [11, 22, 1, 2]

实现

对应 unshift 相对来说比其他三样复杂了一点,我稍微简化了一下

实现思路:

  1. 判断是否传入了参数, 如果没有则返回原数组长度
  2. 保存插入的数组长度
  3. 重点: 循环插入数组元素,其中I为数组前区元素,length为数组后区元素 用于存放i的元素拷贝
  4. 将传入的参数插入到数组的开头
  5. 返回数组的新长度
 Array.prototype.unshift2 = function () {
     const arrLen = this.length;
     const addLen = arguments.length;
     if (arrLen == undefined || arrLen == 0) return undefined;
     const addLen = arguments.length;
     for (let i = arrLen - 1, length = arrLen + addLen - 1; i >= 0; i--, length--) {
         this[length] = this[i];
     }
     for (let i = 0; i < addLen; i++) {
         this[i] = arguments[i];
     }   
     return this.length;
 }

最后

push、pop、shift以及unshift,这4个方法都是数组的常用变更方法,理解并掌握其原理与实现对我们操作和使用数组至关重要。

最后如果本文对于本文有疑惑,还请指导勘正 (●'◡'●)