深拷贝与浅拷贝
深拷贝与浅拷贝
浅拷贝:将原对象或原数组的引用直接赋值给新对象。新对象/新数组只是原对象/原数组的一个引用。
深拷贝:创建一个新对象/数组,将原对象的键/值全部赋值到新对象中,是真值,而非引用。
深拷贝的意义:改变新对象,不影响原对象
堆内存与栈内存
栈内存:存放基本数据类型以及引用类型的地址
堆内存:存放引用类型的真实值
数据结构中的堆与栈
栈:先进后出的数据结构 FIFO
堆:非连续的树形存储结构,根节点是最大的或最小的,用于数据排序
实现单层深拷贝(数组):
方案一:遍历
方案二:array.slice()
- 拷贝数组为基本数据类型时,为深拷贝
- 当数组内部存在引用类型时,为浅拷贝
var arr1 = [1,2,3,4,5,6]
var arr2 = arr1.slice()
方案三:array.concat()
- 拷贝数组为基本数据类型时,为深拷贝
- 当数组内部存在引用类型时,为浅拷贝
var arr1 = [{name:'jeny'},2,3,4]
var arr2 = [].concat(arr1)
arr1[1].name = 'laowang'
console.log(arr1) // [{name:'laowang',2,3,4}]
console.log(arr2) // [{name:'laowang',2,3,4}]
深拷贝对象
方案一:Object.assign(target, source1, source2);
++当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝++
const a = {
name:'name1',
age:'age1'
}
const b = {
name:'name1',
age:'age1'
}
const c = Object.assign(c,a,b)
方案二:ES6扩展运算符
const obj = {
name:'name1',
age:'age1'
}
const {name} = {...obj}
console.log(name) // name1
方案三:JSON.stringify() && JSON.parse() 深拷贝对象/数组大招,拷贝所有层
function deepClone(obj) {
let _obj = JSON.stringify(obj);
let objClone = JSON.parse(_obj);
return objClone;
}
方案四:递归
function _deepClone(source) {
let target;
if (typeof source === 'object') {
target = Array.isArray(source) ? [] : {}
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (typeof source[key] !== 'object') {
target[key] = source[key]
} else {
target[key] = _deepClone(source[key])
}
}
}
} else {
target = source
}
return target
}
方案五:通过jQuery的extend方法实现深拷贝
let $ = require('jquery');
let obj1 = {
a: 1,
b: {
f: {
g: 1
}
},
c: [1, 2, 3]
};
let obj2 = $.extend(true, {}, obj1);
方案六:lodash.cloneDeep()实现深拷贝
let _ = require('lodash');
let obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
let obj2 = _.cloneDeep(obj1);