js-深浅拷贝

深拷贝和浅拷贝

深浅拷贝针对的只是引用类型(array,object,map,set...等等)
复制代码
深浅拷贝的不同:

一.浅拷贝就是简单的对象属性的赋值,而不是递归复制,js的存储对象都是存地址的,所以地址没有改变.

// 值类型的拷贝
var num = 1;
var num2 = num;
num2 = 3;
console.log(num,num2)

//output
1 3

//引用类型的拷贝
var obj = {c:1,d:0};
var obj2 = obj;
obj2.c = 9;
console.log(obj.c,obj2.c)

//output
9 9 

//新对象发生改变,老的对象也会随着变化,就是因为他们指向的是同一个地址
复制代码

浅拷贝的实现方式:

1.Object.assign

    let a = {
        age:1
    }
    let b=Object.assign({},a)
    a.age = 2
    console.log(b.age) //1
复制代码

2.(...)展开运算符

let a = {
    age:1
}
let b={...a}
a.age = 2
console.log(b.age) //1
复制代码

二.深拷贝就是使用递归复制,不仅复制对象的各个属性,还将对象属性所包含的对象复制 ==(对象是有原型链的)==

实现深拷贝的两种方法:

(1)迭代递归法

for ... in (方法) 最常用
Reflect
lodash中的深拷贝
复制代码
 function deepClone(source){
	var target = {};
	for(var i in source){
		if(source.hasOwnProperty(i)) {
			if(typeof source[i] === 'object'){
				target[i] = deepClone(source[i])
			} else {
				target[i] = source[i];
			}
		}
	}
	return target;
}
var obj = {c:1,d:0};
var obj2 = obj;
obj2.c = 3
console.log(obj.c,obj2.c)

///output
1 3	
复制代码

(2)序列化反序列化法(用的较多)

function deepCloneTwo(source){
	return JSON.parse(JSON.stringify(source)) ///重要
}

var obj = {c:1,d:0};
var obj4 = deepCloneTwo(obj);
obj4.c = 0
console.log(obj.c,obj4.c)

//output
1 0 
复制代码

深拷贝数组呢

上述的拷贝操作,对数组(set,map)一样可用

var mapType = {}
var arrType = []
var setType = {}
var testType1 = typeof(mapType)
var testType2 = typeof(arrType)
var testType3 = typeof(setType)
console.log(testType1, '引用')
console.log(testType2, '数据')
console.log(testType3, '类型')

//output

object 引用
object 数据
object 类型
复制代码

原因就是:array object set map 的typeof 都是 object


上面所说的是 多层次的拷贝

如果是只做第一层的拷贝呢:

数组:

1.直接遍历 (push到一个新数组里面)
2.slice()
slice() var copyArray = array.slice(); 方法返回一个从已有的数组中截取一部分元素片段组成的新数组(不改变原来的数组!)
3.concat() var copyArray = array.concat();
concat() 方法用于连接两个或多个数组。( 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。)
复制代码

对象:

1.直接遍历
2.ES6的Object.assign
Object.assign:用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),并返回合并后的target

用法: Object.assign(target, source1, source2);  所以 copyObj = Object.assign({}, obj);  这段代码将会把obj中的一级属性都拷贝到 {}中,然后将其返回赋给copyObj
(以前就接触过,但是没有完全了解)

3.扩展运算符(...)
扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中

但是遇到多吃嵌套: obj.name.firstname
等格式的  都会报错
复制代码

相关文章:juejin.im/post/5ad6b7…

www.cnblogs.com/penghuwan/p…

yanhaijing.com/javascript/…

转载于:https://juejin.im/post/5c4eb4a75188250f743e1b5d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值