一,js中有堆和栈的概念
栈:基本数据类型的值存放在此处
堆:引用数据类型的地址在栈中,真实数据存放在堆中
二,赋值和浅拷贝的区别
var obj1 = {
name:'ming',
age:20,
money:[1,[2,3],[4,5]]
}
// 赋值
var obj2 = obj1;
function shallowCopy(target){
var src = {};
for(var prop in target){
if(target.hasOwnProperty(prop)){
src[prop] = target[prop]
}
}
return src;
}
// 浅拷贝
var obj3 = shallowCopy(obj1);
obj2.name = 'wei';
obj3.age = 30;
obj2.money[0] = '一';
obj3.money[1] = ['二','三'];
console.log(obj1); // wei 20 ['一', ['二','三'],[4,5]]
console.log(obj2); // wei 20 ['一', ['二','三'],[4,5]]
console.log(obj3); // 'ming' 30 ['一', ['二','三'],[4,5]]
赋值:同一个引用对象,原对象任何改变都是引起新赋值的改变
浅拷贝:不同的引用对象,若只有一层,则算是深拷贝;引用对象的属性如果是引用数据类型,则会引起新对象的改变
三,浅拷贝和深拷贝
浅拷贝的复制指向原对象的指针(这里指的是一层之后的引用赋值,对于第一层的简单数据类型,则是传值赋值),深拷贝创建一个一模一样的对象,不共享内存,新旧之间没有任何关联
四,浅拷贝的三种实现方式
1,Object.assign()(Object对象的拷贝)
var obj1 = {
name:'ming',
age:20,
money:[1,[2,3],[4,5]]
}
var obj2 = Object.assign({},obj1);
obj2.money[0] = '一'
console.log(obj1)
和下面一样的是,这里如果只有一层,就是深拷贝
2,Array.prototype.slice()(Array的拷贝)
var arr1 = [1,2,{name:'ming'}]
var arr2 = arr1.concat();
arr2[2].name = 'wei'
console.log(arr1)
3,Array.prorotype.concat()(Array的拷贝)
var arr1 = [1,2,{name:'ming'}];
var arr2 = arr1.slice();
arr2[2].name = 'wei';
console.log(arr1)
五,深拷贝实现
1,JSON.parse(JSON.stringify())
先序列化对象,再解析出来
缺点:无法处理函数
var obj1 = {
name:'ming',
age:20,
money:[1,[2,3],[4,5]],
function(){}
}
// obj拷贝,函数不存在
var arr1 = [1,2,{name:'ming'},function(){}]
// 数组拷贝,函数为null
var obj2 = JSON.parse(JSON.stringify(arr1));
obj2.money[0] = '一';
console.log(obj2)
2,手写递归算法
function checkType(target){
return Object.prototype.toString.call(target).slice(8,-1);
}
function clone(target){
let result , targetType = checkType(target);
// 判断数据类型
if(targetType === 'Object'){
result = {};
}else if(targetType === 'Array'){
result = [];
}else{
return result;
}
// 开始拷贝
for(let value in target){
if(checkType(value) === 'Object' || checkType(value) === 'Object'){
result[value] = clone(value);
}else{
result[value] = target[value]
}
}
return result;
}
var obj1 = {
name:'ming',
age:20,
money:[1,[2,3],[4,5]],
function(){}
}
var obj2 = clone(obj1);
obj2.money = 1
console.log(obj1)
3,lodash库
var _ = require('lodash');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
参考地址: