浅层克隆-深层克隆

我们的数据类型分为原始值和引用值

原始值
存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。由于这些原始类型占据的空间是固定的,所以可将他们存储在较小的内存区域 - 栈中。这样存储便于迅速查寻变量的值
引用值

存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。由于引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响。


  • 原始值:Number、boolean、string、null、undefined
  • 引用值:Array、object、function


浅层克隆

var Foo = {
	name:'xx',
	age:19,
	arr1:[1,2,[2,3]],
	eat:function(){
		var name = 'lll';
	},
	drink:{
		name:'xx'
	}
}
var Son = {}
function clone(Foo,child) {
	var child = child || {};
	for(var prop in Foo) {
		if (Foo.hasOwnProperty(prop)) {
			child[prop] = Foo[prop];
		}
	}
}
clone(Foo,Son)
console.log(Son)

函数的第一句话是什么意思呢?克隆分为两种情况,如果我们有一个对象Foo={//对象内容},然后我们要克隆Foo,我们可以有一个Son={ }用来把内容放进去;但是如果没有Son这个空对象,我们就要自己给创建一个空对象


这是打印结果,客观别急,接着看

clone(Foo,Son)
Foo.name = '阿三';
Foo.age = '30';
console.log(Son)


我们把Foo的name和age都重新赋值,但是克隆出来,并没有变化,是不是大功告成了?

clone(Foo,Son)
Foo.name = '阿三';
Foo.age = '30';
Foo.arr1.push(6,8,9)
console.log(Son)

我们在Foo的arr1数组里面加几个数,然后再克隆看看


name和age没变,但是数组中多了6,8,9三个数,这克隆失败了啊,Foo数据改变,Son也跟着改变了。这是因为上面提到的原始值和引用值的问题,数组属于引用值,所以我们在克隆的时候,是把Foo的地址给了Son,他们指向同一个地址,数据改变,所以Son的克隆值也会变。这种克隆就叫做浅层克隆。


深层克隆

我们的思路是,先判断一下,Foo对象中的属性都是什么类型,如果是数组,我们就创建一个数组,如果是对象,我们就创建一个对象,然后把数据再放进去,如果是原始值,那就直接复制。

判断一个数据的类型的三种方法

  • typeOf 返回一个字符串,来表示数据的类型
  • instanceof 可以用来判断某个构造函数的prototype属性是否存在于另外一个要检测对象的原型链上
  • Object.prototype.toString.call()   这个是判断某一个数据的原型上的toString是什么类型

var Foo = {
	name:'xx',
	age:19,
	arr1:[1,2,[2,3]],
	drink:{
		name:'xx'
	}
}
var Son = {}
function deepClone (Foo,child) {
	var child = child || {};
	for(var prop in Foo) {                		//遍历Foo中的每一个属性
		if (Foo.hasOwnProperty(prop)) {         //判断属性是否为自己本身的,防止添加原型上的属性
			if(typeof(Foo[prop]) == "object"){    		//判断属性类型是否为object
				child[prop] = (Foo[prop].constructor == Array) ? [] : {}; //如果Foo属性的类型是数组,就创建数组,如果不是,就创建对象
				deepClone(Foo[prop],child[prop])
			}else {
				child[prop] = Foo[prop];
			}
		}
	}
}
deepClone(Foo,Son);
Foo.name = '阿三';
Foo.arr1.push(5,6,7);
Foo.drink.age = '99';
console.log(Son)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值