JavaScript之对象的引用篇

89 阅读2分钟

这篇文章和大家说一下js中对象引用的相关知识点。废话不多说,直接上示例。

    let a = 5;
    let b = a;
    b += 3;
    
    alert(a);
    alert(b);

弹窗打印出来的值,分为别58,这是很简单的一种赋值,把a赋给bb的改变不会影响到a的值,这种赋值的关系,存在于基本类型当中。比如字符串,数字,布尔值,undefind,{}。

下面我们来看看复杂类型当中的引用情况:

    let a = [1,2,3];
    let b = a;
    b.push(4);
    
    alert(a);
    alert(b);

上面这种情况,很明显a b打印出来的值都为1,2,3,4,因为对象和函数都是引用的关系,下面我们把代码做一些变动。

    let a = [1,2,3];
    let b = a;
    b = [1,2,3,4]

    alert(a);
    alert(b);

a b打印出来的值,就和上面不一样了,b的赋值并没有影响到a ,相当于重新开辟了一个内存空间。由于对象引用的这种设计,我们在实际开发中,会遇到一些奇奇怪怪的问题。

let obj = {
    a:10
}
let obj2 = obj
obj2.a = 20

alert(obj.a)

由于共用同一个引用,此时弹窗的值为20。当我们使用一个对象,赋值给另一个对象时,对赋值的对象的操作,会影响原来的对象,因此我们就有了深拷贝和浅拷贝的说法。下面我们写一个简单的浅拷贝方法:

let obj = {
    a:10
}

function copy(obj){
    let newObj = {}
    for(let attr in obj){
        newObj[attr] = obj[attr]
    }
    return newObj
}

let obj2 = copy(obj)
obj2.a = 20

alert(obj.a)

运行代码,可以看到,弹窗的值为10,并没有受到新赋值的影响。但是这样的方法并不能处理对象嵌套对象的情况,比如:

    let obj = {
        a:{
            b:10
        }
    }
    function copy(obj){
        let newObj = {}
        for(let attr in obj){
            newObj[attr] = obj[attr]
        }
        return newObj
    }

    let obj2 = copy(obj)
    obj2.a.b = 20

    alert(obj.a.b)

这样还修改了原有对象值,新旧对象,并没有起到相互隔离的效果,因为只拷贝了一层,所以叫做浅拷贝,下面我们递归处理多层,实现深拷贝。

    let obj = {
        a:{
            b:10
        }
    }
    function deepCopy(obj){
        if(typeof obj !== 'object'){
            return obj
        }
        
        
        let newObj = {}
        for(let attr in obj){
            newObj[attr] = deepCopy(obj[attr])
        }
        return newObj
    }

    let obj2 = copy(obj)
    obj2.a.b = 20

    alert(obj.a.b)