1、基本类型复制
var a = 1;
var b = a;//复制
console.log(b)//1
a = 2;//改变a的值
console.log(b)//1
console.log(a) //2
//是地址的赋值,将对象指针赋值给一个变量,让此变量指向对象
因为基本类型(String,Number,Boolean,Null,undefined)是每一次创建变量都会在栈内存中开辟一块内存,用来存放值,所以基本类型进行复制是不会对另外一个变量有影响的
2、引用类型复制----深浅拷贝-------对象/数组
1)浅拷贝------只会将对象的各个属性进行依次复制,并不会进行递归复制。
实现1:遍历实现
var shallowCopy = function(obj) {
// 只拷贝对象
if (!obj && typeof obj !== 'object') return;
// 根据obj的类型判断是新建一个数组还是对象
var newObj = obj instanceof Array ? [] : {};
// 遍历obj,并且判断是obj的属性才拷贝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
其他实现:es6扩展运算符、es6的Object.assin()、数组方法(obj.contact()、obj.slice()、Array.from(obj))
https://blog.csdn.net/a2013126370/article/details/89035722
2)深拷贝-----不仅复制原对象的各个属性,同时也将原对象各个属性所包含的子对象也递归地复制到新对象上。复制后两者是完全不相干的两个对象。
1、JSON.parse(JSON.stringify())
用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。
2、浅拷贝+递归
var deepCopy = function(obj) {
if (typeof obj !== 'object') return;
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}
存在的问题:
没有对传入参数进行校验,传入 null 时应该返回 null 而不是 {}。
对于对象的判断逻辑不严谨,因为 typeof null === ‘object’。
function deepClone(obj){
//判断参数是不是一个对象
let objClone = obj instanceof Array?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
没有考虑数组的兼容
3)其他
jQuery------$.extend()
var obj1 = $.extend({},obj) //浅拷贝
var obj2 = $.extend(true,{},obj) //深拷贝
函数库lodash-------_.clone()
/ _.cloneDeep()
var obj1=_.clone(obj) //浅拷贝
var obj2= _.cloneDeep(obj) //深拷贝