1.数据类型
最新的 ECMAScript 标准定义了8种数据类型:
七种基本数据类型包括 Boolean,null,undefined ,Number,BigInt,String,Symbol。
还有一种引用类型 Object。
基本数据类型存储在 栈(stack),占内存空间固定,使用后被销毁
而引用类型存储在 堆(heap),占内存空间不固定,使用后不一定被销毁
基本数据类型拷是对值的复制,将保存与复制的是值本身,两份数据在内存中是完全独立的。
引用类型是对引用的复制,保存与复制指向对象地址一个指针,当两个变量中一个修改了对象的值,另一个变量来访问时也会访问到修改后的值。
2.对象拷贝
var first = {
a : "first",
b: [1, 2, 3],
c: {
c1: 1
}
}
var second = first;
second.a = "second";
second.c.c1 = 2;
second.b[0] = 5;
console.log(first); // a:"second" b:[5,2,3] c:{c1:2}
第一种:浅拷贝()
对象 es6解构赋值 ,Object.assign()
var first = {
a : "first",
b: [1, 2, 3],
c: {
c1: 1
}
}
var second = Object.assign({},first);
//var second = {...first}
second.a = "second";
second.c.c1 = 2;
second.b[0] = 5;
console.log(first); // a:"first" b:[5,2,3] c:{c1:2}
second 修改拷贝对象a属性时没问题,但在修改复杂数据类型属性b, c后影响到源对象,所以当对象内不包含数组或对象时,该方法不失为一个快速创建对象拷贝的实用方法
数组 Array.prototype.slice(), Array.prototype.concat()
var first = [1,{a:'1'},{a:'2'},{a:'3'}]
var second = first.concat();
console.log(first===second); //false
// var second = first.slice();
second[0] = 3;
second[1].a = "5";
console.log(first); // 1 {a:'5'} {a:'2'} {a:'3'}
console.log(second); // 3 {a:'5'} {a:'2'} {a:'3'}
对一维数组有用,当有对象存在时无效。
其他浅拷贝 jQuery的$.extend({}, obj)
第二种:深拷贝
JSON.parse(JSON.stringify(obj))
JSON.stringify() 首先将对象序列化为字符串,再由JSON.parse() 反序列化为对象,形成新的对象。
var first = {
a : "first",
b: [1, 2, 3],
c: {
c1: 1
}
}
var second = JSON.parse(JSON.stringify(first));
second.a = "second";
second.c.c1 = 2;
second.b[0] = 5;
console.log(first); // a:"first" b:[1,2,3] c:{c1:1}
JSON.parse(JSON.stringify(obj)) 在 undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)
其他深拷贝jQuery的$.extend(true, {}, obj), lodash的_.cloneDeep和_clone(value, true)
简单实现浅拷贝和深拷贝:https://www.jianshu.com/p/264069c15651
参考资料:https://segmentfault.com/a/1190000016036099
https://segmentfault.com/a/1190000013278803#item-1
https://www.jianshu.com/p/2188dcd91090