关于javascript的浅拷贝和深拷贝

基础须知

数据类型之基础类型

5种基本数据类型Undefined、Null、Boolean、Number 和 String,变量是直接按值存放的,存放在栈内存中的简单数据段,可以直接访问。

数据类型之引用类型

地址指针在栈内存中,实际数据在堆内存中。存放在堆内存中的对象,变量保存的是一个指针,这个指针指向另一个位置。当需要访问引用类型(如对象,数组等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

概述

JavaScript存储对象都是存地址的,所以浅拷贝会导致 obj1 和obj2 指向同一块内存地址。改变了其中一方的内容,都是在原来的内存上做修改会导致拷贝对象和源对象都发生改变,而深拷贝是开辟一块新的内存地址,将原对象的各个属性逐个复制进去。对拷贝对象和源对象各自的操作互不影响。

浅拷贝只是让拷贝对象拥有了只想对象数据的指针地址,深拷贝才会字对内存中真正复制一份

这里有个点大家要注意下,对于function类型,一般是直接赋值的,还是共享一个内存值。这是因为函数更多的是完成某些功能,有个输入值和返回值,而且对于上层业务而言更多的是完成业务功能,并不需要真正将函数深拷贝

深拷贝实现

function deepClone(data) {
    var t = type(data), o, i, ni;
    
    if(t === 'array') {
        o = [];
    }else if( t === 'object') {
        o = {};
    }else {
        return data;
    }
    
    if(t === 'array') {
        for (i = 0, ni = data.length; i < ni; i++) {
            o.push(deepClone(data[i]));
        }
        return o;
    }else if( t === 'object') {
        for( i in data) {
            o[i] = deepClone(data[i]);
        }
        return o;
    }
}

Array的slice和concat方法

Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。之所以把它放在深拷贝里,是因为它看起来像是深拷贝。而实际上它是浅拷贝。
取决于数组的值是基础类型还是引用类型。

JSON对象的parse和stringify

JSON对象parse方法可以将JSON字符串反序列化成JS对象,stringify方法可以将JS对象序列化成JSON字符串,借助这两个方法,可以实现对象的深拷贝。

jQuery.extend()方法

jQuery的extend方法使用基本的递归思路实现了浅拷贝和深拷贝

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,768评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,171评论 1 32
  • 面试的时候,经常会被问到js的浅拷贝和深拷贝问题,很多时候能够想清楚是怎么回事,但是实在描述不出来,可能还是自己比...
    肆意咯咯咯阅读 366评论 0 3
  • 今天一如既往地不能说话,这次拔智齿貌似比较厉害,都三天了还不消肿,明天继续打针。 连续三天只喝粥,我的胃要受不了了...
    杨淑心阅读 167评论 1 0
  • 嘿嘿几乎想偷懒儿不码字了呢!又开始迷恋电影了,什么美人鱼呀,新版三打白骨精呀看得那叫一个入迷停不下来。近日积食不消...
    凡阳nihao阅读 226评论 0 3