浅拷贝与深拷贝的主要区别

浅拷贝与深拷贝的主要区别在于对象属性的复制方式。浅拷贝只复制对象的直接属性,如果属性是基本类型,则复制其值;如果属性是引用类型,则复制引用,而不是复制引用的对象本身。深拷贝则复制对象的所有属性,包括引用类型属性的副本。

Java中的实例

易错浅拷贝实例

在Java中,如果不正确地实现clone方法,可能会导致浅拷贝。

public class Address {
    private String street;

    // 忽略构造函数、getter和setter
}

public class Person implements Cloneable {
    private String name;
    private Address address;

    // 忽略构造函数、getter和setter

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 错误的浅拷贝实现,没有复制Address对象
        return super.clone();
    }
}

Person original = new Person("John", new Address("123 Main St"));
Person copy = (Person) original.clone();

original.getAddress().setStreet("456 Elm St");

// 浅拷贝,共享Address对象,输出:456 Elm St
System.out.println(copy.getAddress().getStreet());
正确的深拷贝写法

在Java中,正确的深拷贝需要确保所有引用类型属性都被正确复制。

public class Address implements Cloneable {
    private String street;

    // 忽略构造函数、getter和setter

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Person implements Cloneable {
    private String name;
    private Address address;

    // 忽略构造函数、getter和setter

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.address = (Address) address.clone(); // 正确的深拷贝
        return cloned;
    }
}

Person original = new Person("John", new Address("123 Main St"));
Person copy = (Person) original.clone();

original.getAddress().setStreet("456 Elm St");

// 深拷贝,Address对象是独立的,输出:123 Main St
System.out.println(copy.getAddress().getStreet());

JavaScript中的实例

易错浅拷贝实例

在JavaScript中,使用Object.assign或扩展运算符(...)进行浅拷贝时,需要注意引用类型属性的问题。

const original = {
    name: 'John',
    address: { street: '123 Main St' }
};

// 使用Object.assign进行浅拷贝
const copy = Object.assign({}, original);

original.address.street = '456 Elm St';

// 浅拷贝,共享address对象,输出:456 Elm St
console.log(copy.address.street);
正确的深拷贝写法

在JavaScript中,可以使用JSON.parse(JSON.stringify(obj))来实现深拷贝,但要注意它不能处理函数和循环引用。

const original = {
    name: 'John',
    address: { street: '123 Main St' }
};

// 使用JSON方法进行深拷贝
const copy = JSON.parse(JSON.stringify(original));

original.address.street = '456 Elm St';

// 深拷贝,address对象是独立的,输出:123 Main St
console.log(copy.address.street);

请注意,JSON.parse(JSON.stringify(obj))方法并不是万能的,它不能处理复杂的对象,例如包含函数、循环引用或者特殊对象(如DateRegExp等)的对象。在这种情况下,可能需要使用库如lodash_.cloneDeep方法来实现深拷贝。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值