数据类型分为简单数据类型和复杂数据类型。对于基本数据类型来说,它的值直接存储在栈内存中,而对于引用类型来说,它在栈内存中仅仅存储了一个引用地址,而真正的数据存储在堆内存中。
对于Js简单数据类型有5种,Number,String,Boolean,undefined,null;、
复杂数据类型:Object(注意:数组属于对象)
浅拷贝
对于浅拷贝而言,就是只拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一对象,任何一个修改都会使得所有对象的值修改,因为它们公用一条数据。
深拷贝
深拷贝作用在引用类型上!例如:Object,Array
深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型,这样就不会发生引用错乱的问题,使得我们可以多次使用同样的数据,而不用担心数据之间会起冲突。
深拷贝实现的几种方法
1.通过 JSON 对象实现深拷贝
//通过js的内置对象JSON来进行数组对象的深拷贝
var obj1 = {
a: 1,
b: 2,
c: 3,
md:{
name:'zs'
}
}
function deepClone(obj) {
var newobj = JSON.stringify(obj), //将对象转换为字符串
objClone = JSON.parse(newobj); //将字符串转换为对象
return objClone;
}
var obj2 = deepClone(obj1);
obj2.a=2;
console.log(obj1.a);//1
console.log(obj2.a);//2
obj2.md.name='ls'
console.log(obj1.md.name);//zs
console.log(obj2.md.name);//ls
Tips:使用JSON.stringify()以及JSON.parse()它是不可以拷贝 undefined , function, RegExp 等等类型的
2.Object.assign(target, source)
var obj1 = {
a: 1,
b: 2,
c: ['a','b','c']
}
var obj2 = Object.assign({}, obj1);
obj2.c[1] = 5;
obj2.a=2;
console.log(obj1.c); // ["a", 5, "c"]
console.log(obj2.c); // ["a", 5, "c"]
console.log(obj1.a); //1
console.log(obj1.b); //2
Tips:当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。
3.递归拷贝
// 深拷贝拷贝多层, 每一级别的数据都会拷贝.
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
},
color: ['pink', 'red']
};
var o = {};
function deepCopy(newobj, oldobj) {
for (var k in oldobj) {
// 判断我们的属性值属于哪种数据类型
var item = oldobj[k];
// console.log(k);
// console.log(item);
// 2. 判断这个值是否是数组
if (item instanceof Array) {
newobj[k] = [];
deepCopy(newobj[k], item) //[],['pink', 'red']
} else if (item instanceof Object) {
// 3. 判断这个值是否是对象
newobj[k] = {};
deepCopy(newobj[k], item)
} else {
// 4. 属于简单数据类型
newobj[k] = item;
}
}
}
deepCopy(o, obj);
console.log(o);
Tips:null、undefinde、function、RegExp等特殊的值也能拷贝成功
4.通过jQuery的extend方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array);
5.lodash函数库实现深拷贝
lodash很热门的函数库,提供了 lodash.cloneDeep()实现深拷贝