前言
什么是重构呢?很多人只觉得我知道怎么用就行了嘛,干嘛还重构它内部怎么实现的,就像我也不用知道1+1=2的原理呀。站在javascript的角度,我的理解就是重构一个方法让自己可以更加深入理解这个方法的使用,什么时候应该出现什么,这时候你就会发现你自己使用的时候可以会更加自信。并且在使用数组方法过程中如果出现错误,自己也可以快速发现错误,并且纠正。
怎么重构?
首先 ,我会从这个数组方法的功能性去重构。我们拿splice来说吧,我们只知道这个方法可以删除数组元素和添加。但是我们其他情况我们也应该知道。当然,这里说的不全。总之,你需要知道它的种种情况,才能用好它。接下来就开始我们的重构吧。
1.这个方法有没有参数?有几个参数?
2.参数不填的时候,会出现什么情况?
3.参数乱填或者说不小心填错了会出现什么?
4.参数超过范围了会怎么样?
5.参数能填什么样的数据类型,不同数据类型会不会转换?
splice
首先我们知道splice是有多个参数的,第一个参数是删除或添加的起始索引,第二个参数是删除个数,往后的都是需要添加的数据了,一个或者多个。其返回值是一个被删除元素组成的数组。返回的是一个新数组,并且原数组也会改变。
var arr = [1,2,3,4,5];
//从索引1开始删除3个元素,添加的元素有4,5(从索引为1开始)
//输出[2,3,4] [1,4,5,5],第一个是被删除的数组第二个是删除后被添加完成之后的原数组
console.log(arr.splice(1,3,4,5),arr);
var arr1 = [2,3,4,5,6]
// false 说明返回的和原数组引用地址都不一样
console.log(arr1.splice(1,3,4,5)==arr1);
接下来我们可以判断参数的其他情况了,例如如果用户给的是字符串会如何。给的数值小于0,或者要删除的个数大于数组的个数.....我们代码里具体介绍
function arrSplice(arr,start,deleteCount,...arg){
//判断操作的数组是否为数组
if(!arr && arr.constructor !== Array)throw new TypeError(arr+'.splice is not a function');
//创建最后需要返回的数组,现在是空的,待会一个一个加上
var deleteAr = [];
//如果一个参数都没有的话,说明不删除元素
if(start == undefined) return deleteAr;
// 能到这儿说明 start参数已经给了,这时候要删除的个数就是数组最大长度了
if(deleteCount === undefined) deleteCount = arr.length;
/*
~ 是位取反,将数值转换为二进制进行取反,简单点来说 让数值加一取反,~~就是向下
取整了,因为~是转换为二进制计算的,二进制会自动舍去小数,还有一个作用就是用于
将非数字都转换为0,在这其中会先将非数值转换为数值,如果转换不了会直接为0
*/
start = ~~start;
// 和上面情况一样。
deleteCount = ~~deleteCount;
// 如果个的参数(起始索引)大于数组的长度的话那么就让其为数组的长度
if(start > arr.length) start =arr.length;
// 如果删除的个数小于0,就不删除,让其为0
if(deleteCount < 0 )deleteCount=0;
// 当start小于0,那么就是从后往前
if(start < 0) start = start+arr.length<0 ? 0 : start+arr.length;
// 这里计算出具体在数组中能删除的个数
var len = start+deleteCount > arr.length ? arr.length-star : deleteCount;
// 先从索引star开始删除,遍历数组
for(var i=start;i<arr.length;i++){
// 如果从开始循环到要删除的个数之前,把这些元素全部存储在删除的数组中
// 保证放进去的都是要删除的元素
if(i < start+len) deleteAr[deleteAr.length] = arr[i];
//将后面的对应位置的元素挪到当前位置,从当前位置+删除的个数间隔
if(i+len in arr) arr[i] = arr[i+len];
// 这个情况是当被挪动的原始是一个空值,这时候使用delete 就可以将其赋为空值
else{
arr[i] = null;
delete arr[i];
}
}
// 删除过后的数组,最后几位都已经被转移到前面去了,所以这里就可以将当前数组长度
// 减去被删除的个数元素的长度
arr.length -= len;
// 接下来就是需要插入元素了,...agr是需要插入元素的列表
//是需要插入元素,所以需要从后向前循环,当前数组的长度+要插入元素的个数
// 循环到开始位置
for(var j = arr.length+arg.length-1;j>=start;j--){
//如果当前时挪动这个过程 ,将从开始+添加个数之后的位置处理挪动
if(j>start+arg.length-1){
if(j-arg.length in arr)arr[j]=arr[j-arg.length]
// 如果是空元素,先添加任意值,然后使用delete删除,造成空元素
else{
arr[j] = null;
delete arr[j];
}
// 如果当前不是挪动的,需要将插入的元素放在当前位置,
// 因为下标从start开始,所以需要-start
}else arr[j] = arg[j-start]
}
// 返回之前被删除元素的数组
return deleteAr;
}
总之,需要全面的考虑可能出现的情况,尽可能的去试错。因为在这过程中,你就会增长你对其了解程度了,可千万别出现问我为什么删除个数小于0为什么就直接为0了,因为规则不是我定的。我们只是去遵循javascript所制定去使用方法。
最后....如果你看懂了的话,或者留言。还有记得收藏加点赞哈!!!