15、克隆

克隆

浅层克隆

把obj的属性都克隆到obj1身上了,但是浅层克隆是指obj的属性值发生变化之后obj1的属性值不改变,原始值只是复制了一份。但是引用值会发生改变,会互相影响,因为引用的是地址,指向同一个值。

var obj = {
    name : 'abc' ,age : 123,
    sex : 'female' ,
    card : [ 'visa ' , ' unionpay']
}
var obj1 = {}
function clone(origin, target) {
    // 防止用户不传target
    var target = target || {};
    for(var prop in origin) {
   	 target [prop] = origin [prop];
    }
   	 return target;
}
clone(obj, obj1);

// 往obj1中添加属性值  会发现obj中也会增加
obj1.card.push('master'); 

image-20221005193634179

深层克隆

属性一模一样,但是就不是同一个,也就是各自更改互不干预。

// 思路
// 遍历对象  for(var prop in obj)  
// for in 除了遍历对象之外也能遍历数组
// 1. 依次判断属性值是原始值还是引用值 原始值直接写 typeof() obj是引用值  其他类型都是原始值
// 2. 引用值要判断是数组还是对象 instanceof toString constructor
// 3. 建立相应的数组或对象
// 4. 递归

var obj ={
    name : "abc" ,
    age : 123,
    card : ['visa','master'],
    wife : {
        name : "bcd" ,
        son :{
       		name : "aaa"
    	}
    }
}

// 思路理解
var obj1 = {
    // 原始值之间的拷贝是占内存的拷贝 直接赋值
    name : "abc",
    age : 123,
    // 引用值也是直接赋值 但是赋的是地址 建立新数组 判断被拷贝数组中是原始值还是引用值  原始值直接拿过来
    card : ['visa','master'],
    // 对象和数组类似
    wife : {
        ame : "bcd",
        // son不是原始值 就需要建立新的对象  然后继续判断son中是否原始值
        son : {
            name : "aaa"
        }
    }
}
// 思路
// 遍历对象  for(var prop in obj)  
// for in 除了遍历对象之外也能遍历数组
// 1. 依次判断属性值是原始值还是引用值 原始值直接写 typeof() obj是引用值  其他类型都是原始值
// 2. 引用值要判断是数组还是对象 instanceof toString constructor
// 3. 建立相应的数组或对象
// 4. 递归

var obj ={
    name : "abc" ,
    age : 123,
    card : ['visa','master'],
    wife : {
        name : "bcd" ,
        son :{
       		name : "aaa"
    	}
    }
}

var obj1 = {
    
}

// 写法
function deepClone(origin, target) {
    var target = target || {},
   		tostr = 0bject.prototype.toString,
         arrStr = "[object Array]";  // 用于后面判断
    for(var prop in origin) {  // 第一步 遍历对象
   		if(origin.hasOwnProperty(prop)) { // 先判断是不是自己的属性  过滤掉原型上的属性  原型上的属性不拷贝
            if(typeof(origin[prop]) == 'object' && origin[prop]) !== "null") { // 判断是不是引用值
               /* if(toStr.call(origin[prop] == arrStr) { 判断
                   	target[prop] = [];引用值是数组就建立新数组
                   }else {
                       target[prop] = {};
                   } */
            target[prop] = (toStr.call(origin[prop] == arrStr ? [] : {})
      // 让他俩递归  继续循环执行函数 直到找到全部原始值后退出循环
				deepClone(origin[prop],target[prop]);  
            }else {
                target[prop] = origin[prop]; // 原始值直接赋值
            }
	}
    return target;  // 如果没传target 需要把target return出去
}

给obj.card增加一个属性进去,访问obj1.card会发现没有这个属性,也就说明了两者互不影响

image-20221005204603156

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好好学习_fighting

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值