js简单实现深浅克隆
浅度克隆:原始类型为值传递,引用类型仍为引用传递。改变原对象中的引用类型中的值,后者对象中的值也会被改变。
深度克隆:所有元素或属性均完全复制,与原对象完全脱离,改变原对象中的引用类型中的值,后者对象中的值并不会随其改变。
主要思路浅克隆直接复制第一层中的值,深克隆通过递归来实现
定义函数将其挂载到Object的原型上,函数接收一个参数,用做判断是深克隆还浅克隆,传递参数为true代表深刻隆,传递false或者不传代表浅克隆。然后通过判断其操作的数据类型来实现
- 如果该数据是funtion类型,直接返回该数据
- 如果该数据是array类型,遍历数组中的每一项,在根据传递的参数来判断是否深或者浅克隆,如果是深刻隆继续递归调用该函数,在把返回的值放入新数组中,如果是浅克隆,直接将值放入新数组中。
- 如果该数据是object类型,和数组一样直接遍历其中的值,在判断深浅克隆,最后将数据放入新对象中返回该对象
- 如果是不是引用数据类型,是基本数据类型就直接返回该值
代码如下
Object.prototype.myReplication = function (deep) {
//判断该值是类型是否是function,如果是直接返回
if (typeof this == 'function') {
return this
} else if (this instanceof Array) {
//判断该值是否是是否是数组
//声明一个新数组
var newArr = []
//循环遍历数组中的每一项
for (let i = 0; i < this.length; i++) {
//判断是否要深度克隆,如果要深度克隆递归调用该函数将调用
//返回的值添加进新数组,如果不是直接添加进新数组
deep ? newArr.push(this[i].myReplication(deep)) : newArr.push(this[i])
}
//返回该新数组
return newArr
} else if (Object.prototype.toString.call(this) == "[object Object]") {
//判断其该值是否是一个对象
//声明一个新对象
let obj = {}
//遍历该对象中的每一项的键值对
for (let j in this) {
//判断j是否是对象本身的属性
if(this.hasOwnProperty(j)){
//判断是否深克隆还是浅克隆,如果是深克隆再次用该值递归调用该函数添加函数返回的值,
//如果是浅克隆直接添加该值
obj[j] = deep ? this[j].myReplication(deep) : this[j]
}
}
//最后返回该新对象
return obj
} else {
//如果是基本数据类型直接返回,调用其的tostring方法避免在调用函数的过程中
//被转换成包装类对象
return this.toString()
}
}