深拷贝和浅拷贝

23次阅读

共计 404 个字符,预计需要花费 2 分钟才能阅读完成。

说起深浅拷贝其实就是数据内存,堆栈问题。

基本数据类型值指保存在栈内存中的简单数据段

var a=1

操作的是变量实际保存的值。a = 2;

基本类型变量的复制:从一个变量向一个变量复制时,会在栈中创建一个新值,然后把值复制到为新变量分配的位置上。var b= a;
栈内存

引用数据类型:引用数据类型值指保存在堆内存中的对象。也就是,变量中保存的实际上的只是一个指针,这个指针指向内存中的另一个位置,该位置保存着对象。访问方式是按引用访问。

vara = new Object();

当操作时,需要先从栈中读取内存地址,然后再延指针找到保存在堆内存中的值再操作
a.name= ‘xz’;

引用类型变量的复制:复制的是存储在栈中的指针,将指针复制到栈中未新变量分配的空间中,而这个指针副本和原指针指向存储在堆中的同一个对象;复制操作结束后,两个变量实际上将引用同一个对象。因此,在使用时,改变其中的一个变量的值,将影响另一个变量。
var b= a;

正文完
 0

深拷贝和浅拷贝

23次阅读

共计 1160 个字符,预计需要花费 3 分钟才能阅读完成。

只有对于 Object(复杂数据类型)才有深浅拷贝一说

1、粗浅的解释:

  • 浅拷贝并不是真的拷贝,新对象仍指向原被拷贝对象的内存地址,如有更新会被同步

(引用数据类型(Object)的名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值)

  • 深拷贝是完全拷贝出了独立的对象,一毛一样

2、怎样实现深拷贝

递归方式

function deepClone(obj){let objClone = Array.isArray(obj)?[]:{}; 
    // 判断是否为引用类型数据
    if(obj && typeof obj==="object"){for(key in obj){if(obj.hasOwnProperty(key)){
                // 判断 ojb 子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){objClone[key] = deepClone(obj[key]);
                }else{
                    // 如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    
let a=[1,2,3,4],
    b=deepClone(a);
a[0]=2;
console.log(a,b);    // 2234 1234

extend(jQuery 方法)

$.extend([ deep], target, object1 [, objectN] )
deep 表示是否深拷贝,为 true 为深拷贝,为 false,则为浅拷贝

let a=[0,1,[2,3],4],
    b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

借用 JSON 对象的 parse 和 stringify

利用 JSON.stringify 将 js 对象序列化(JSON 字符串),再使用 JSON.parse 来反序列化 (还原)js 对象; 序列化的作用是存储 (对象本身存储的只是一个地址映射,如果断电,对象将不复存在,因此需将对象的内容转换成字符串的形式再保存在磁盘上) 和传输(例如 如果请求的 Content-Type 是 application/x-www-form-urlencoded,则前端这边需要使用 qs.stringify(data)来序列化参数再传给后端,否则后端接受不到)

function deepClone(obj){let _obj = JSON.stringify(obj),
        objClone = JSON.parse(_obj);
    return objClone
}    
let a=[0,1,[2,3],4],
    b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);  

使用 JSON 做深拷贝时,被拷贝对象内如果有 date、RegExp 或者是 function 会出现一些问题

正文完
 0