js中的浅拷贝和深拷贝

谈浅拷贝和深拷贝之前,先了解js中的值类型,我们知道的类型有Number、string、Array、Boolean、Object、null、undefined、Function,其中基础类型包括Number 、string、Boolean、null、undefined,他们是按值访问的,我们可以直接操作保存在变量中的值。引用类型包括Array、Object、Function,他们的值是存在堆内存中的,js不允许直接访问,只能通过引用访问。

例如我们定义一个a:

var a = 1;

那么js会在栈内存分配出空间,存放a和值1

var b = a;

这时,栈内存会再分配出新的空间,来存放b和值1

namevalue
a1
b1

a和b是互相独立的,所以

a = 10;

console.log(a,b)   // 10,1

我们再定义一个对象obj1:

var obj1 = {

    name: 'tom',

    age: 24

}

这里js会把obj1存放到栈内存中去,把值放到堆内存中,我们只能通过obj1来获取到值,可以理解为obj1存放了一个指针,指向堆中值所在的位置

var obj2 = obj1;

这时,只是把obj1的指针赋给了obj2

obj1指针(堆地址)

name: 'tom',

age: 24

obj2指针(堆地址)

当我们更改obj1对象的值时,obj2就会同时变化,因为他俩是一个对象。。。这种情况就是所谓的浅拷贝了

那么怎样才能实现把obj1对象赋值给一个新的对象呢?这就是要说的深拷贝

我们可以试着定义一个空的对象:

var obj2 = {}

把obj1中的属性照着添加就可以了,这样就是完全重新创建了一个对象

obj2.name = 'tom';

obj2.age = 24;

当然,一般对象中的属性很多,并且属性可能是引用类型的值,所以我们可以用函数按照这个思路来封装一下,用递归的方法来实现

function deepCopy(obj) {
    let newObj = Array.isArray(obj)? [] : {};
    if(obj && typyof(obj) == 'object'){
        for(key in obj){
            //因为对象会沿着原型链查找属性,所以这里判断是否是对象自己的属性是有必要的
            if(obj.hasOwnProperty(key)){
                //判断属性是否为对象
                if(obj[key] && typeof(obj[key] === 'object')) {
                    newObj[key] = deepCopy(obj[key]);
                }else{
                    //否则就直接简单赋值
                    newObj[key] = obj[key]
                }
            } 
        }
    }
    return newObj;
}

 

除了递归,我们还可以使用JSON对象的序列化和解析,也会返回一个新的对象

function deepCopy(obj) {
    let a = JSON.stringify(obj);
    let b = JSON.parse(a);
    return b;
}

当然,在学习jquery的时候,jquery也提供了一个全局方法$.extend()

$.extend(deep, target, object1[,objectN])

deep: boolean true是深拷贝,false是浅拷贝

target:新生成的对象

object1 objectN: 要被合并的对象

好了,那么在实际开发中,当我们每次从服务器获取到返回值时,如果返回的是一个对象,而这个对象可能在多个地方要使用到,那么为了不影响其他函数使用,最稳妥的办法就是深拷贝一个新的对象,然后再使用。

那么,暂时就想到这些了

 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值