JS深浅拷贝与赋值
JavaScript基本数据类型的变量存储在栈中,引用数据类型则存储在堆中,但是引用数据类型的存储地址则保存在栈中。
-
赋值
当我们把一个对象赋值给一个新的变量时候,赋的其实是该对象在栈中的地址,而不是堆中的数据,也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。
var programmer = { name: '张三', attr: ['前端', ['Vue', 'React', 'Angular'], '后端'] } var programmer1 = programmer programmer1.name = 'lisi' programmer1.attr[0] = '测试' console.log(programmer) console.log(programmer1)
-
浅拷贝
重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会相互影响
// 方法一 var programmer = { name: '张三', attr: ['前端', ['Vue', 'React', 'Angular'], '后端'] } function shallowClone(obj) { var target = {} for (let i in obj) { if (obj.hasOwnProperty(i)) { target[i] = obj[i] } } return target } var programmer1 = shallowClone(programmer) programmer1.name = 'lisi' programmer1.attr[0] = '测试' console.log(programmer) console.log(programmer1) // 方法二 var programmer1 = {...programmer} programmer1.name = 'lisi' programmer1.attr[0] = '测试' console.log(programmer) console.log(programmer1) // 方法三 var programmer1 = Object.assign({}, programmer) programmer1.name = 'lisi' programmer1.attr[0] = '测试' console.log(programmer) console.log(programmer1) // 方法四 // 还有lodash中的 _.clone(),这里就不演示了
-
深拷贝
从堆内存中开辟一个新的区域存放新对象,对对象中的子对象进行递归拷贝,拷贝前后的两个对象互不影响
// 方法一 var programmer = { name: '张三', attr: ['前端', ['Vue', 'React', 'Angular'], '后端'] } function deepClone(obj) { let target if (typeof obj === 'object') { if (Array.isArray(obj)) { target = [] for (let i in obj) { target.push(deepClone(obj[i])) } } else if (obj === null) { target = null } else if (obj instanceof Date) { target = new Date(obj) } else if (obj instanceof RegExp) { target = new RegExp(obj) } else { target = {} for (let i in obj) { target[i] = deepClone(obj[i]) } } } else { target = obj } return target } var programmer1 = deepClone(programmer) programmer1.name = 'lisi' programmer1.attr[0] = '测试' console.log(programmer) console.log(programmer1) // 方法二 var programmer1 = JSON.parse(JSON.stringify(programmer)) programmer1.name = 'lisi' programmer1.attr[0] = '测试' console.log(programmer) console.log(programmer1) // 方法三 // lodash中的 _.cloneDeep() 这里就不演示了