JS中数组的splice()方法介绍 及 用原生JS手写数组splice()方法

一、splice是什么

splice()方法是用来对数组进行增、删操作,该方法返回被删除的元素,改变原数组

二、splice()方法接受三个及以上的参数:

第一个参数: 第一个参数是起始位置(数组的索引)
第二个参数: 第二个参数是要删除的元素个数,如果该参数是负数则默认为0
第三个参数及往后参数: 这些参数是准备要添加进数组的参数

三、参数介绍

1.如果第一个参数为正数 从索引 1 开始删除后面的所有元素包括自身

    let arr = [1, 2, 3, 4, 5]
      let newArr = arr.splice(1) // 从索引 1 开始删除后面的所有元素包括自身
      console.log(arr) // [1]
      console.log(newArr) // [2, 3, 4, 5]

2.如果第一个参数大于最大索引值 则返回空数组

       let arr = [1, 2, 3, 4, 5]
       let newArr = arr.splice(5) // 大于最大索引值(4)
       console.log(arr) // [1, 2, 3, 4, 5]
       console.log(newArr) // []

3.如果第一个参数是一个负数 从数组末端开始删除元素删除的个数为参数值

      let arr = [1, 2, 3, 4, 5]
      let newArr = arr.splice(-2) // 从数组末端删除 2 个元素
      console.log(arr) // [1, 2, 3]
      console.log(newArr) // [4, 5]

4.如果第一个参数为负数并且该负数的绝对值要小于或等于数组长度

      let arr = [1, 2, 3, 4, 5]
      let newArr = arr.splice(-5) // 该参数的绝对值小于等于数组长度
      console.log(arr) // []
      console.log(newArr) // [1, 2, 3, 4, 5]

四、当有两个参数时,第一个参数为起始位置,第二个参数是要删除元素的个数,如果第二个参数为负数则默认为0

 let arr = [1, 2, 3, 4, 5]
      let newArr = arr.splice(2, 2) // 两个参数  起始值从索引0开始算 这里起始值为3 删除两个元素包括自身
      console.log(arr) // [1,2,5]
      console.log(newArr) // [3, 4]
 
      let arr1 = [1, 2, 3, 4, 5]
      let newArr1 = arr1.splice(-2, 2) // 从数组末尾开始算起始值为数组元素中的3  删除两个元素包括自身
      console.log(arr1) // [1,2,3]
      console.log(newArr1) // [4, 5]

五、原生JS手写splice()方法

思路

1、当参数只有一个时,判断该参数的特殊情况和正常情况

特殊情况:

(1). 当参数的值为undefined 那么直接将该参数赋值为0 (2). 当该参数的值比数组最后一个元素的索引值还大 那么直接返回一个空数组 (3). 当该参数为0,或者该参数的绝对值比数组的长度还大或者传递进来的不是数字,那么给最终要返回的数组赋值,并且原数组的长度设置为0

正常情况:

1、该参数是一个合理的正数和合理的负数,那么通过for循环给新数组赋值,减少原数组的长度

2、当参数有两个时,先判断第二个参数是否合理,为负数或者不是数字转换为0

调用自定义的方法,把第一个参数传进去获取被删除的所有元素,在通过slice方法截取出第二个参数要被删除的个数

3、当参数有三个及以上时, 通过判断第一个参数得到一个起始位置start,

如果第一个参数为负数且它的绝对值大于原数组的长度,那么起始位置就是0,否则就是原数组的长度加上第一个参数,如果第一个参数为正数且在数组最后一个元素索引的范围内,那么起始位置就是第一个参数

调用自定义方法,把前面两个参数传进去,获得被删除的元素,用(middle)表示,此时的this(原数组)就是剩余的元素,把left先赋值给最后将要返回的数组,在将middle清空,将第三个及以上的参数push进middle中,这样就得到了由新元素组成的数组,此时的原数组就是剩下的参数,通过起始位置截取this,得到end数组,在把this起始位置前的元素删除掉,那么就得到了头部(this),中间部分(middle),右边(end),再分别把中间部分和右边部分push到this中就得到了一个改变后的新数组

    Array.prototype.mySplice = function () {
        // 最终返回的新数组
        let newArr = []
        // 一个参数
        if (arguments.length === 1) {
          // 如果第一个参数传入的是undefined或null 直接赋值为0
          if (arguments[0] === undefined) {
            arguments[0] = 0
          }
          // 如果第一个参数比数组最后一个索引还大 那就一个都不会删除 直接返回空数组
          if (arguments[0] > this.length - 1) {
            return newArr
          }
          // 如果第一个参数是负数小于原数组的负值    第一个参数为0     第一个参数传入进来的不是数字
          if (arguments[0] <= -this.length || arguments[0] == 0 || typeof arguments[0] === 'string') {
            // 给newArr赋值
            newArr = [...this]
            // 清空原数组
            this.length = 0
            return newArr
          }
          // 如果是一个合理的负数
          if (arguments[0] < 0 && arguments[0] > -this.length) {
            // 转为正数
            arguments[0] *= -1
            // 遍历第一个参数的起始位置
            for (let i = 0; i < arguments[0]; i++) {
              // 从第0项起给newArr
              newArr[i] = this[this.length - arguments[0] + i]
            }
            // 如果第一个参数为负数 就是从数组末尾开始删除第一位参数值的元素
            this.length -= arguments[0]
            return newArr
          }
          // 如果是正数 并且在合理范围内
          if (arguments[0] > 0 && arguments[0] <= this.length - 1) {
            for (let i = this.length - 1; i > arguments[0] - 1; i--) {
              // 将删除的元素赋值给newArr
              newArr[i - arguments[0]] = this[i]
              // 每循环一次数组长度减1
              this.length--
            }
            return newArr
          }
        }
 
        // 两个参数
        if (arguments.length === 2) {
          // 第二个参数为负数默认为0     为字符串              为undefined 或null
          if (arguments[1] < 0 || typeof arguments[1] === 'string' || arguments[1] === undefined) {
            arguments[1] = 0
          }
          //  删除部分   假如只有一个参数 拿到被删除的部分
          let deletePart = this.mySplice(arguments[0])
 
          //  剩下的     从合适的位置截取出不需要被删除的元素
          let residue = deletePart.slice(arguments[1])
 
          //  截取出被删除的放入新数组中  从0开始截取出被删除的元素
          let newArr = deletePart.slice(0, arguments[1])
 
          // 遍历没有被删除的元素 push到this中
          for (let i = 0; i < residue.length; i++) {
            this.push(residue[i])
          }
          return newArr
        }
 
        // 三个参数及以上
        if (arguments.length >= 3) {
          // 定义哪里开始删除的位置
          let start = null
          // 如果 第一个参数比原数组的负长度还小 那就赋值为0
          if (arguments[0] <= -this.length) {
            arguments[0] = 0
            start = 0
          } else {
            // 转为正数后的起始值: 例子 start = 6 + -1
            start = this.length + arguments[0]
          }
          // 有效正数范围内的起始值
          if (arguments[0] >= 0 && arguments[0] < this.length) {
            start = arguments[0]
          }
          // 拿到被删除的元素           arr = [1, 2, 3, 4, 5, 6]   arr.mySplice(3,2,0,0)
          let result = this.mySplice(arguments[0], arguments[1]) // resulte:[5,6]
          // 截取被删除的元素
          let newArr = result.slice(0, arguments[1]) // 获取返回值 newArr:[5,6]
          // 将要添加的元素放入被删除的素组中
          for (let i = 2; i < arguments.length; i++) {
            result.push(arguments[i]) // resulte:[5,6,0,0]
          }
          // 删除被删除的元素 剩下的就是需要添加的元素
          for (let i = 0; i < newArr.length; i++) {
            result.shift(arguments[i]) // results:[0,0]
          }
 
          // start:3   this:[1,2,3,4]
          let end = this.slice(start === 0 ? arguments[1] : start) // end:[6]
 
          if (start === 0) {
            for (let i = 0; i < result.length; i++) {
              this.unshift(result[i])
            }
          } else {
            for (let i = 0; i < end.length; i++) {
              this.pop() // this:[1,2,3]
            }
            for (let i = 0; i < result.length; i++) {
              this.push(result[i]) // this:[1,2,3,0,0]
            }
            for (let i = 0; i < end.length; i++) {
              this.push(end[i]) // this:[1,2,3,0,0,6]
            }
          }
          return newArr
        }
      }

转自于:https://zhuanlan.zhihu.com/p/716070842

posted @ 2024-10-21 09:12  Ao_min  阅读(1017)  评论(0编辑  收藏  举报