JS中的深克隆和浅克隆

实现浅克隆

浅克隆概念

1.使用arr1=arr2的语法不会克隆数组(arr1与arr2都是数组,此时arr2与arr1相同,指向同一个地址)。
2.浅克隆:只克隆数组或对象的第一项,如果是多维数组或对象的属性有引用类型值,则不可隆其它层。
3.如何实现浅克隆:

实现浅克隆

准备一个空的结果数组,然后使用for循环遍历原数组,将遍历到的项都推入结果数组
浅克隆只克隆数组的一层,如果数组是多维数组,则克隆项会“藕断丝连”

    var arr1= [1,2,3,4,5]
    var arr3 = arr1     //没有实现克隆,arr3与arr1仍指向同一个地址
    var arr2=[1,2,3,4,[5,6,7]]
    var result1=[]
    var result2  =[]
    // 遍历数组中的每一项,把遍历到的项推入到结果数组中
    for(var i=0;i<arr1.length;i++){
        result1.push(arr1[i])
    }
    for(var i=0;i<arr2.length;i++){
        result2.push(arr2[i])
    }
   console.log(result1)    //[1,2,3,4,5]
   console.log(result1 == arr1)   //false,此时实现了克隆,result和arr指向不同的地址(引用类型值==比较的是内存地址)
   console.log(result2)    //[1,2,3,4,[5,6,7]]
   console.log(result2[4]==arr2[4])   //true,藕断丝连,并没有完全分离,实现的是浅克隆

使用for…in…即可实现对象的浅克隆

<script>
		var person = {
			name:'张三',
			age:26,
			sex:'男',
			job:{
				work:'程序员',
				salary:15000
			}
		}
		var personClone = {}
		for(var k in person){
			// 每遍历一个k属性,就给personClone添加一个同名的属性
			// 值和person的k属性值相同
			personClone[k] = person[k]
		}
		console.log(personClone)    //浅克隆成功  age: 26 job: {work: '程序员', salary: 20000} name: "张三" sex: "男"
		console.log(person == personClone)   //false
		person.name = "李四"
		console.log(personClone.name)    //张三
		person.job.salary = 20000   
		console.log(personClone.job.salary)   //20000
		console.log(person.job.salary == personClone.job.salary)   //true  藕断丝连
	</script>

实现深克隆

深克隆概念

1.深克隆:克隆数组或对象的所有层,需要使用到递归技术

实现深克隆

使用递归的思想,整体思路和浅克隆一样,但稍微进行一些改动;如果遍历到项是基本类型值,则直接推入结果数组;如果遍历到的项又是数组,则重复执行浅克隆的操作。

   var arr1 = [3, 2, 4, 1, [12, 10, [11, 16]]]
    //    定义一个函数,这个函数会被递归
    function deepClone(arr) {
        // 定义一个结果数组
        // 每一次递归的时候都要生成一个结果数组,所以定义在函数里面
        var result = []
        // 遍历数组的每一项
        for (var i = 0; i < arr.length; i++) {
            // 类型判断,如果遍历到的项都是数组
            if (Array.isArray(arr[i])) {
                // 递归再次遍历数组
                result.push(deepClone(arr[i]))
            } else {
                // 如果遍历到的项不是数组,是基本类型值,就直接推入到结果数组中
                // 相当于是递归的出口
                result.push(arr[i])
            }
        }
        //  返回结果数组
        return result
    }
    var arr2 = deepClone(arr1)
    console.log(arr2)
    console.log(arr1[4] == arr2[4])     //false,已经成功克隆,在内存内是不同的地址

以下是对象和数组都包含在一起的深克隆

<script>
		var person = {
			name:'张三',
			age:26,
			sex:'男',
			job:{
				time:"八点",
				work:["作家","UI设计师","程序员",{
				author:'2000每月',
				UIdesiger:'9800每月',
				coder:'15000每月'
			}]
			}
		}
		function deepClone(o){
        // 判断传进来的o是数组还是对象
      //这里判断数组和对象的先后顺序不能变,因为用typeof检测数组返回的也是object,所以先检测数组
		if(Array.isArray(o)){
			// 传进来的是数组
			var result = []
			for(var i=0;i<o.length;i++){
				result.push(deepClone(o[i]))
			}
		}else if(typeof o == 'object'){
			// 传进来的是对象
			var result = {}
			for(var k in o){
				result[k] = deepClone(o[k])
			}
			}else{
				//是基本类型值
				var result = o
			}
			return result
		}
		var personClone = deepClone(person)    
		console.log(personClone)    //深克隆完全复制过来
		console.log(person.job == personClone.job)   ///false
		console.log(person.job.work == personClone.job.work)   //false
		person.job.work[3].coder = "30k每月"       //更改源的coder值   
		console.log(personClone.job.work[3].coder)    //15000每月
 		person.job.time = '九点半'     //更改源的time值
		console.log(personClone.job.time)   //八点
	</script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值