当前位置: 移动技术网 > IT编程>网页制作>CSS > 深拷贝与浅拷贝的区别以及实现方式介绍

深拷贝与浅拷贝的区别以及实现方式介绍

2018年04月10日  | 移动技术网IT编程  | 我要评论

头两天面试遇到拷贝方面的问题,不过当时并没有给面试官一个满意的回答。所以,今天我们来深入探索一下深浅拷贝。

在说深浅拷贝之前,我们先来聊聊JavaScript变量的基本类型(undefined,boolean,number,string,null)与引用类型(Array,Object)。基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象。

基本类型

基本类型在内存中分别占有固定大小的空间,他们的值保存在栈空间,我们是通过按值来访问的。 引用类型

引用类型,值大小不固定,栈内存中存放地址指向堆内存中的对象。是按引用访问的。栈内存中存放的只是该对象的访问地址,在堆内存中为这个值分配空间。由于这种值的大小不固定,因此不能把它们保存到栈内存中。但内存地址大小的固定的,因此可以将内存地址保存在栈内存中。 这样,当查询引用类型的变量时, 先从栈中读取内存地址, 然后再通过地址找到堆中的值。对于这种,我们把它叫做按引用访问。(这是别的哥们总结的,非常棒!我直接把原话拿过来了。)

由此可得出:基本类型的比较是值的比较,只有在它们的值相等的时候它们才相等。引用类型的比较是引用的比较,只有引用地址和值同时相等的时候它们才相等。同时它们之间一个最大的区别在于:基本类型是按值传递,引用类型是按引用传递。这里需要注意的是:深浅拷贝只适用于array与object。

浅拷贝只复制指向某个对象的引用地址,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。

这样说可能显得很抽象,我们举例说明:

浅拷贝实现

方法一:赋值运算符

var a = [1, 2, 3],
    b = a
console.log(a) //[1, 2, 3]
console.log(b) //[1, 2, 3]
b[0] = 99;
console.log(a) //[99, 2, 3]
console.log(b) //[99, 2, 3]

方法二:for in 循环

var obj = {a: 1,arr: [2, 3]};
        var shallowObj = shallowCopy(obj);
        function shallowCopy(src) {
            var copyObj = {};
            for (var i in src) {
                if (src.hasOwnProperty(i)) {
                    copyObj[i] = src[i];
                }
            }
            return copyObj;
        }
        console.log(obj);  //{a: 1,arr: [2222, 3]}
        shallowObj.arr[0] = 2222;
        console.log(shallowObj);  //{a: 1,arr: [2222, 3]}

从上面的实现代码不难看出!浅拷贝只是引用地址的拷贝,不管更改任何一方都会影响到另一方,因为它们根本就是同一个对象。

深拷贝实现

方法一:递归拷贝

var mySelf = {name: '猫哆哩',hobby: ['敲代码', '玩游戏', '打台球']};
        function deepCopy(p, c) {    
            var c = c || {};    
            for (var i in p) {      
                if (typeof p[i] === 'object') {        
                    c[i] = (p[i].constructor === Array) ? [] : {};        
                    deepCopy(p[i], c[i]);      
                } else {         
                    c[i] = p[i];      
                }    
            }    
            return c;  
        }  
        var Doctor = deepCopy(mySelf);
        Doctor.hobby.push('听音乐');
        console.log(mySelf);  //{name: '猫哆哩',hobby: ['敲代码', '玩游戏', '打台球']};
        console.log(Doctor);  //{name: '猫哆哩',hobby: ['敲代码', '玩游戏', '打台球', '听音乐']};

所谓”深拷贝”,就是能够实现真正意义上的数组和对象的拷贝。它的实现并不难,只要递归调用”浅拷贝”就行了。

方法二:jquery的$.extend()

jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象。

这里写图片描述

这里需要特别强调一下 deep 参数,简单的说deep为true就是深拷贝,为false就是浅拷贝。

当然,还有很多方法可以实现深浅拷贝。在这里就不多废话了!重点是我TM更博的速度确实慢,这也是自身能力不足,不知道写什么好。总之,任重道远、贵在坚持吧。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网