深拷贝和浅拷贝的区别
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力
为什么要使用深拷贝?
我们希望在改变新的数组(对象)的时候,不改变原数组(对象)
深拷贝的要求程度
我们在使用深拷贝的时候,一定要弄清楚我们对深拷贝的要求程度:是仅“深”拷贝第一层级的对象属性或数组元素,还是递归拷贝所有层级的对象属性和数组元素?
怎么检验深拷贝成功
改变任意一个新对象/数组中的属性/元素, 都不改变原对象/数组
深拷贝数组(只拷贝第一级数组元素)
深拷贝数组
1.直接遍历
var array = [1, 2, 3, 4];
function copy (array) {
let newArray = []
for(let item of array) {
newArray.push(item);
}
return newArray;
}
var copyArray = copy(array);
copyArray[0] = 100;
console.log(array); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]
2. slice()和concat()
深拷贝对象
1.直接遍历
var obj = {
name: '彭湖湾',
job: '学生'
}
function copy (obj) {
let newObj = {};
for (let item in obj ){
newObj[item] = obj
}
return newObj;
}
var copyObj = copy(obj);
copyObj.name = '我才不是彭湖湾呢! 哼 (。・`ω´・)';
console.log(obj); // {name: "彭湖湾", job: "学生"}
console.log(copyObj); // {name: "我才不是彭湖湾呢! 哼 (。・`ω´・)", job: Object}
2.ES6的Object.assign
var obj = {
name: '彭湖湾',
job: '学生'
}
var copyObj = Object.assign({}, obj);
copyObj.name = '我才不叫彭湖湾呢! 哼 (。・`ω´・)';
console.log(obj); // {name: "彭湖湾", job: "学生"}
console.log(copyObj); // {name: "我才不叫彭湖湾呢! 哼 (。・`ω´・)", job: "学生"}
Object.assign:用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),并返回合并后的target
3.ES6扩展运算符:
var obj = {
name: '彭湖湾',
job: '学生'
}
var copyObj = { ...obj }
copyObj.name = '我才不叫彭湖湾呢! 哼 (。・`ω´・)'
console.log(obj.name) // 彭湖湾
console.log(copyObj.name) // 我才不叫彭湖湾呢! 哼 (。・`ω´・)
扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
4.Jquery浅拷贝 var copiedObject = jQuery.extend({}, originalObject)
如果改变了originalObject,copiedObject 也会变。
对多层嵌套对象,很遗憾,上面四种方法,都会失败:
深拷贝(拷贝所有层级)
1.不仅拷贝第一层级,还能够拷贝数组或对象所有层级的各项值
2. 不是单独针对数组或对象,而是能够通用于数组,对象和其他复杂的JSON形式的对象
1.JSON.parse(JSON.stringify(obj))
当obj为对象时,这个方法会省略那些值为 functions 和 undefined 的属性,值为null还返回null
当obj为数组时,如果数组里有function 、undefined、null,序列化后都变成null
2.手动写递归
var array = [
{ number: 1 },
{ number: 2 },
{ number: 3 }
];
function copy (obj) {
var newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
}
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
copy(obj[i]) : obj[i];
}
return newobj
}
var copyArray = copy(array)
copyArray[0].number = 100;
console.log(array); // [{number: 1}, { number: 2 }, { number: 3 }]
console.log(copyArray); // [{number: 100}, { number: 2 }, { number: 3 }]
3.jQuery深拷贝 var copiedObject = $.extend(true, {}, originalObject)