简单的来说就是,在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误!
在js中,对于非基本类型数据(普通对象或数组),浅拷贝只是拷贝了内存地址,子类属性指向父类属性的内存地址,而子类修改后父类也会被修改
在js中,对于非基本类型数据(普通对象或数组),浅拷贝只是拷贝了内存地址,子类属性指向父类属性的内存地址,而子类修改后父类也会被修改
看程序
<script type="text/javascript">
var a={
name:'liu',
age:12,
address:{ //父对象的address属性是另外两个对象,而不是简单数据类型
home:'home1',
school:'xiaoxue'
}
}
var b={
sex:'boy'
}
function extend(a,b){
for(var prop in a){
b[prop]=a[prop];
}
}
extend(a,b);
b.address.home='home2';
console.log(a.address.home);
console.log(b.address.home);
</script>
程序中,父对象a的属性没有定义为基本数据类型(基本数据类型的定义都会开辟新的内存),而是又指向了另外两个对象属性,这时子类从父类里拷贝的address属性是address的内存地址,也就是说子类和父类指向同一个内存块,改变了子类也就改变了父类。
解决这一问题,需要深拷贝
<script type="text/javascript">
var a = {
name: 'liu',
age: 12,
address: {
home: 'home1',
school: 'xiaoxue'
}
}
var b = {
sex: 'boy'
}
function extend(a, b) {
for(var prop in a) {
//判断是否是基本数据类型
if(typeof a[prop] === "object") {
b[prop] = (a[prop].constructor === Array) ? [] : {};//对象和数组区别处理
extend(a[prop], b[prop]);
} else {
b[prop] = a[prop];
}
}
}
extend(a, b);
b.address.home = 'home2';
console.log(a.address.home);
console.log(b.address.home);
</script>
如此,子类拷贝父类而不改变父类,实现了所谓继承。
当然深拷贝只是实现继承的一种最基本的方式,还可以通过构造方法,使用call来进行继承,或者直接用prototype原型链来实现继承。