20-封装一个方法,传入目标对象和key(数组和索引),通过传入的索引判断数组是新增还是修改
其实判断新增和修改方法可以一个判断传入的length和数组的长度比较就可以得出,下面的代码是为了体会在vue3中实现reactivity方法对数组的拦截处理,数组会执行两次,一次是索引,一次是length,为了使得执行一次,写了一些方法判断,下面的代码是处理这个判断写了一些方法扩展下思路仅供体会
注:forEach循环数组的索引类型是Number类型,for in 循环的数组索引是String类型
var arr = [1, 2, 3, 4, 5]
var oldArr = JSON.parse(JSON.stringify(arr))
var arr2 = [10, 20, 30, 40, 50]
var obj = {}
/*
1.首先判断是不是一个数组
2.判断传入的索引是否<数组的length,如果小于说明是修改,否则新增
*/
/**
* @param target 传入目标对象
* @param key key 索引传字符串
*/
function isJudgeFn(target, key, value) {
// 如果是数组并且传入的是个索引
if (isArray(target) && isIntegerFn(key)) {
// 返回索引 < 数组长度 -> 意味着是修改
if (Math.abs(Number(key)) < target.length) {
target[key] = value
return 'edit'
} else {
// 如果索引不存在,说明就是新增,如果索引是负数,也是新增
if (!arrKeysHasFn(target, key)) {
target.push(value)
return 'add'
}
}
} else {
return new Error('传入的不是一个数组')
}
}
// var res = isJudgeFn(arr, '1', 61)
// console.log(`这是${res}后的数组,数组为:${arr},原数组为:${oldArr}`,);
// --------------------------------------------------------------------------------------
// 第二种写法判断 :
function isJudgeFn2(target, key) {
// 如果是数组并且传入的是个索引(而不是length)
if (isArray(target) && isIntegerFn(key)) {
// 传入索引<数组长度 为true,代表修改,反之新增
return Math.abs(Number(key)) < target.length
} else {
// 传入索引存在为true,length也为true,因为length是数组的私有属性, 为true代表修改,反之新增
return arrKeysHasFn(target, key)
}
}
// let [target, key, value] = [arr2, '1', 555]
let [target, key, value] = [arr2, 'length', 2]
var hasKey = isJudgeFn2(target, key)
console.log(hasKey);
if (!isArray(target)) {
console.log(new Error('不是数组'));
} else {
if (hasKey) {
target[key] = value
console.log('修改操作,最新的arr2:', arr2);
} else {
target.push(value)
console.log('新增操作,最新的arr2:', arr2);
}
}
// ------------------------------------工具方法:---------------------------------------
// 1 .是否是数组
function isArray(target) {
return Array.isArray(target)
}
// 2.传入的key是不是索引,如果不相等,说明传入的是字符串(传入的是个属性'length'),否则相等说明传入的是索引(索引是string类型)
function isIntegerFn(key) {
return parseInt(key) + '' === key
}
// 3.数组索引是否存在
function arrKeysHasFn(target, key) {
return Object.prototype.hasOwnProperty.call(target, key)
}