深拷贝
深拷贝和浅拷贝的区别
1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”
为什么要使用深拷贝
我们希望在改变新的数组(对象)的时候,不改变原数组(对象)
深拷贝拷贝数组和对象
深拷贝数组
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()
slice() 方法返回一个从已有的数组中截取一部分元素片段组成的新数组(不改变原来的数组!)
用法:array.slice(start,end) start表示是起始元素的下标, end表示的是终止元素的下标
当slice()不带任何参数的时候,默认返回一个长度和原数组相同的新数组
3 . concat()
concat() 方法用于连接两个或多个数组。
用法:array.concat(array1,array2,…,arrayN)
也即把返回数组和一个空数组合并后返回
深拷贝对象
1遍历
2 用JSON的方法
1).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
用法: Object.assign(target, source1, source2); 所以 copyObj = Object.assign({}, obj); 这段代码将会把obj中的一级属性都拷贝到 {}中,然后将其返回赋给copyObj
2)当然我们也可以用JSON.stringify和JSON.parse()
先转化为字符串,在转换回来
var test ={
name:{
xing:{
first:'张',
second:'李'
},
ming:'老头'
},
age :40,
friend :['隔壁老王','宋经纪','同事']
}
var result = JSON.parse(JSON.stringify(test))
result.age = 30
result.name.xing.first = '往'
result.friend.push('fdagldf;ghad')
console.dir(test)
console.dir(result)
缺点:不能拷贝函数
3 .ES6扩展运算符:
扩展运算符(…)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
- 使用递归
var china = {
nation : '中国',
birthplaces:['北京','上海','广州'],
skincolr :'yellow',
friends:['sk','ls']
}
//深复制,要想达到深复制就需要用递归
function deepCopy(o,c){
var c = c || {}
for(var i in o){
if(typeof o[i] === 'object'){
//要考虑深复制问题了
if(o[i].constructor === Array){
//这是数组
c[i] =[]
}else{
//这是对象
c[i] = {}
}
deepCopy(o[i],c[i])
}else{
c[i] = o[i]
}
}
return c
}
var result = {name:'result'}
result = deepCopy(china,result)
console.dir(result)
怎么检验深拷贝成功
改变任意一个新对象/数组中的属性/元素, 都不改变原对象/数组
以上仅供参考,若有不对还望指出