Mr.J--JS学习(Clone)

本文探讨了JavaScript中对象的克隆技术,区分了原始类型和对象类型的克隆差异,详细解析了浅层克隆与深层克隆的概念及其实现方式,通过实例展示了如何避免克隆对象与原对象之间的引用问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

克隆

一、对象的克隆

Javascript中的数据类型分为两大类:原始类型和对象类型。
    (1)原始类型包括:数值、字符串、布尔值、null、undefined。
    (2)对象类型包括:对象即是属性的集合,当然这里又两个特殊的对象----函数(js中的一等对象)、数组(键值的有序集合)。

  这两种类型在复制克隆的时候是有很大区别的。原始类型存储的是对象的实际数据,而对象类型存储的是对象的引用地址(对象的实际内容单独存放,为了减少数据开销通常存放在内存中)。

二、克隆的概念

  浅度克隆:原始类型为值传递,对象类型仍为引用传递。

  深度克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。

三、浅层克隆

简单的克隆一般都能写出来,将这个对象克隆过去不就是把它在被克隆对象里面复制一下。浅层克隆非常简单:

		//浅层克隆
		var obj = {
			name : 'json',
			age : 34,
			sex : 'male',
			card : ['visa','unionpay']		
		}
		
		var obj1 = {};
		
		function clone(origin,target){
			var target = target || {};
			for(var  prop in origin){
				target[prop] = origin[prop];
			}
			return target;
		}
		
		clone(obj,obj1);

运行结果:

从上面的运行结果能够看出给原始值克隆容易实现。但是如果给obj1(克隆对象)的引用值(例如数组)增加数组元素。两个对象的card数组都发生了变化。这就产生了bug。

四、深层克隆

从浅层克隆可以看出原始值的克隆没有问题,但是引用值得改变会让被克隆对象发生改变,然而我们本意是只想克隆,然后自己添加元素,并不想改变克隆对象的元素。

设计思想:

        遍历对象  for(var prop in obj)
        1.判断是不是原始值   typeof()   Object
        2.判断是数组还是对象    instanceof  toString constructor
        3.建立相应的数组或对象
        递归

这五大步骤即可实现深层克隆,即改变obj1不会改变obj得元素,代码实现:

function deepClone(origin,target){
			
			var target = target || {},
				toStr = Object.prototype.toString,
				arrStr = "[object Array]";    //数组类型
			
			for(var prop in origin){
				if(origin.hasOwnProperty(prop)){
					//不为空以及不是原始值
					if(origin[prop] !== "null"  && typeof(origin[prop]) == 'object'){
						
						if(toStr.call(origin[prop]) == arrStr){
							target[prop] = [];
						}else{
							target[prop] = {};
						}
						//递归实现深层遍历
						deepClone(origin[prop],target[prop]);
						//原始值直接复制
					}else{
						target[prop] = origin[prop];
					}
					
				}
			}
			return target;
		}

运行结果:

other : 

function deepClone(origin,target){
			
			var target = target || {},
				toStr = Object.prototype.toString,
				arrStr = "[object Array]";    //数组类型
			
			for(var prop in origin){
				if(origin.hasOwnProperty(prop)){
					//不为空以及不是原始值
					if(origin[prop] !== "null"  && typeof(origin[prop]) == 'object'){
		                          //三目运算符
						target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {};
						//递归实现深层遍历
						deepClone(origin[prop],target[prop]);
						//原始值直接复制
					}else{
						target[prop] = origin[prop];
					}
					
				}
			}
			return target;
		}
		

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值