数据分为根本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型。
- 根本数据类型的特点:间接存储在栈(stack)中的数据
- 援用数据类型的特点:存储的是该对象在栈中援用,实在的数据寄存在堆内存里
援用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找援用值时,会首先检索其在栈中的地址,获得地址后从堆中取得实体。
深拷贝和浅拷贝是只针对Object和Array这样的援用数据类型的。最基本的区别在于是否真正获取一个对象的复制实体,而不是援用。
假如B复制了A,批改A的时候,看B是否发生变化:
如果B跟着也变了,阐明是浅拷贝,拿人手短!(批改堆内存中的同一个值)
如果B没有扭转,阐明是深拷贝,自食其力!(批改堆内存中的不同的值)
浅拷贝(shallowCopy)只是减少了一个指针指向已存在的内存地址,深拷贝(deepCopy)是减少了一个指针并且申请了一个新的内存,使这个减少的指针指向这个新的内存,
应用深拷贝的状况下,开释内存的时候不会因为呈现浅拷贝时开释同一个内存的谬误。
浅复制:仅仅是指向被复制的内存地址,如果原地址产生扭转,那么浅复制进去的对象也会相应的扭转。
深复制:在计算机中开拓一块新的内存地址用于寄存复制的对象。
浅拷贝实例:
//此递归办法不蕴含数组对象 var obj = { a: 1, arr: [2, 3] }; var shallowObj = shallowCopy(obj); function shallowCopy(src) { var newobj = {}; for (var prop in src) { if (src.hasOwnProperty(prop)) { newobj[prop] = src[prop]; } } return newobj; }
因为浅复制只会将对象的各个属性进行复制,并不会进行递归复制,而JavaScript存储对象是存地址的,所以浅复制会导致Obj.arr和shallowObj.arr指向同一块内存地址:
导致的后果就是:
shallowObj.arr[1] = 5;
console.log(obj.arr[1]); //5
深拷贝实例:
var obj = { a: 1, arr: [1, 2], nation: '中国', birthplaces: ['北京', '上海', '广州'] }; var obj2 = { name: '杨' }; obj2 = deepCopy(obj, obj2); console.log(obj2); //深复制,要想达到深复制就须要用递归 function deepCopy(o, c) { var c = c || {}; for (var i in o) { if (typeof o[i] === 'object') { if (o[i].constructor === Array) { //这是数组 c[i] = []; } else { //这是对象 c[i] = {}; } deepCopy(o[i], c[i]); } else { c[i] = o[i]; } } return c; }
而深复制则不同,它不仅将原对象的各个属性一一复制进来,而且将原对象各个属性所蕴含的对象也顺次采纳深复制的办法递归复制到新对象上。这就不会存在obj和shallowObj的arr属性指向同一个对象的问题。
这样obj1和obj2别离领有不同的内存地址,两边的值扭转互不影响。
浅拷贝实现:
var a = [1, 2, 3, 4, 5]; var b = a; a[0] = 2 console.log(a); console.log(b);//因为b浅拷贝a, ab指向同一个内存地址(堆内存中存的值)//b会随着a的变动而变动//[2, 2, 3, 4, 5]//[2, 2, 3, 4, 5]
深拷贝实现:
function deepClone(obj) { var newObj = obj instanceof Array ? [] : {}; if (typeof obj !== 'object') { return obj; } else { for (var i in obj) { newObj[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]; } } return newObj; } var a = [1, 2, 4, 6, "a", "12", [1, 2]]; var b = deepClone(a); a[3] = 7; console.log(a); console.log(b); //b对象并没有因为a对象的扭转而扭转,因为b深拷贝a [ 1, 2, 4, 7, 'a', '12', [ 1, 2 ] ] [ 1, 2, 4, 6, 'a', '12', [ 1, 2 ] ]