1、以前的做法
let origin = {
a:1,
b:3,
f:['dd','pp'],
c:{
d:'嵌套的'
}
}
// 浅克隆
function clone(target) {
if(typeof target == 'object' && target != null){
let copy = Array.isArray(target) ? [] :{}
for(let key in target) {
if(!copy.hasOwnProperty(key)){
copy[key] = target[key]
}
}
return copy
}else{
return false
}
}
// 深克隆
function deepCopy(target){
if(typeof target == 'object' && target != null){
let copy = Array.isArray(target)? [] :{}
for(let key in target){
if(target.hasOwnProperty(key)){
copy[key] = deepCopy(target[key])
}
}
return copy
}else{
// 值不为对象了 返回给 copy[key]
return target
}
}
let copy = deepCopy(origin)
console.log('复制',copy)
console.log('原',origin)
2、偶然间第二次编写,同时对比vue源码中写法
// 定义一个工具函数 判断是否为对象
function isObj(val){
return Object.prototype.toString.call(val) === '[object Object]'
}
注:这里就没做严谨判断和区分数组之类的,正式使用需要完善
**最初版**
function copy(target) {
if(isObj(target)){
const result = {}
for(const key in target){
if(!result[key]){
// 在这里 再次判断若为对象,则递归操作
if(isObj(target[key])){
result[key] = copy(target[key])
}else{
result[key] = target[key]
}
}
}
return result
}else{
return target
}
}
**再来对比 vue源码中的**
function copy(target) {
if(isObj(target)){
const result = {}
for(const key in target){
// 开始做了类型判断,非对象(先不谈数组),直接返回值,故这里直接递归操作
result[key] = copy(target[key])
}
return result
}else{
return target
}
}
3、总结
对比Vue中的写法,我的简直是画蛇添足,首先,进入循环,本来就是空对象,没有必要判断是否含有,(又不是去重),其次,可以利用类型的判断直接进行递归操作,不得不说 完败
最后 附上 VUE源码深拷贝完整写法
function deepClone (val) {
if (isPlainObject(val)) {
const res = {}
for (const key in val) {
res[key] = deepClone(val[key])
}
return res
} else if (Array.isArray(val)) {
return val.slice()
} else {
return val
}
}
ps:vue router中写法
function clone (value) {
if (Array.isArray(value)) {
return value.map(clone)
} else if (value && typeof value === 'object') {
const res = {}
for (const key in value) {
res[key] = clone(value[key])
}
return res
} else {
return value
}
}
4、在完善下数组中嵌套对象之类的
function deepCopy(data) {
if(isObj(data)){
const reslut = {}
for(const key in data){
reslut[key] = deepCopy(data[key])
}
return reslut
}else if(Array.isArray(data)){
const arr = []
//其实也就多了这一步,将数组再次遍历下,再次递归下
data.forEach((item,index)=>{
arr[index] = deepCopy(item)
})
return arr
}else{
return data
}
}
个人思路:
浅拷贝
首先要复制一个对象,肯定要新创建一个空对象
进入逻辑(省去健壮部分),遍历这个对象
逐次添加到新对象中
深拷贝
前面几步差不多,深拷贝主要考虑到对象的嵌套,即属性值,可能也为对象/数组
主要用递归思想
这里就分几种情况 :
1.当 (递归这个原对象的值)不为对象了,则不用进入循环,并将这个值本身 返回给对应的 key
2.任然为对象时,一直循环调用