深拷贝和浅拷贝
数据类型存储
JavaScript
中存在两大数据类型:
浅拷贝
浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝
如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址
1 2 3 4 5 6 7 8 9
| function shallowClone(obj) { const newObj = {}; for(let prop in obj) { if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }
|
在JavaScript
中,存在浅拷贝的现象有:
Object.assign
Array.prototype.slice()
, Array.prototype.concat()
- 使用拓展运算符(
...
)实现的复制
深拷贝
深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
方法一:JSON.stringify()
以及JSON.parse()
这种方法不可以拷贝 undefined
, function
, RegExp
等类型
1 2 3 4 5 6 7 8 9 10
| var obj5 = { a: 1, b: 2, c: 3 } var objString = JSON.stringify(obj5); var obj6 = JSON.parse(objString); obj5.a = 5; console.log(obj5.a); console.log(obj6.a)
|
方法二:递归拷贝
可以拷贝function
,但是不可以拷贝 undefined
, RegExp
等类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| const obj1 = { age: 20, name: '王明洁', address: { city: '杭州' }, arr: ['a', 'b', 'c'] }
const obj2 = deepClone(obj1) obj1.address.city = '上海' console.log(obj2.address.city)
function deepClone(obj={}){ if(typeof obj !== 'object' || obj == null) { return obj } let result if(obj instanceof Array) { result = [] } else { result = {} }
for(let key in obj) { if(obj.hasOwnProperty(key)) { result[key] = deepClone(obj[key]) } } return result }
|
小结
前提为拷贝类型为引用类型的情况下:
- 浅拷贝是拷贝一层,属性为对象时,浅拷贝是复制,两个对象指向同一个地址
- 深拷贝是递归拷贝深层次,属性为对象时,深拷贝是新开栈,两个对象指向不同的地址