先介绍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
}
}