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