js深拷贝、浅拷贝同时对比VUE源码写法

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.任然为对象时,一直循环调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值