js的数据类型,深拷贝和浅拷贝的原理,loda实现一个深拷贝

js的数据类型分为:简单类型 和 复杂类型;
简单类型:
string, number, null, undefined, Symbol
复杂数据类型:
function, array, object, Date, Math, 正则

简单数据类型是存储在栈中,复杂数据类型存储在 堆中;
堆的空间比栈的空间大;
简单数据类拷贝是在栈中开辟了一个空间,地址不一样;
复杂的数据类型拷贝的时候是在堆中的,只是在栈中开辟了两个空间(指针)去指向堆,两个的地址是一样的,所以一个改变的时候另外一个也会改变;

 

假如要是简单数据类型实现一个拷贝复制,那么拷贝后的值并不会随着拷贝的改变,是个深拷贝;

a = 1
b = a
a = 2
console.log(b) // b 值仍然为1

 

 


假如有一个复杂类型的一个浅拷贝

a={
v:'123'
}
b = a
a.v = '456'
console.log(b) // b 的值也随着改变了 为456

 


复杂数据类型实现深拷贝的办法?

1,使用JSON.parse(JSON.stringify(要拷贝的对象))
优点:二级以下也可以实现深拷贝
缺点:无法拷贝function,undefined,正则

2,使用 Object.assign(obj1, obj2)
优点:可以拷贝function,undefined,正则
缺点:二级以下不能实现深拷贝

3,使用递归
写一个公共拷贝的函数方便调用,先判断他的类型,之后进行遍历 for in,拿到所对应的key 的值后进行deepClone1进行深拷贝,在返回就好了;

//使用递归的方式实现数组、对象的深拷贝
function deepClone1(obj) {
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
var objClone = Array.isArray(obj) ? [] : {};
//进行深拷贝的不能为空,并且是对象或者是
if (obj && typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone1(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}

安装lodash

$ cnpm i lodash -S 使用lodash 实现一个深拷贝

import _ from 'lodash'
var obj = {id:1,name:{a:'xx'},fn:function(){}};
var obj2 = _.cloneDeep(obj);
obj2.name.a = 'obj2';
console.log(obj,obj2)

posted on 2021-03-23 18:50  多一点  阅读(171)  评论(0编辑  收藏  举报

导航