当前位置:人工智能 > 【js基础知识】深拷贝方法

【js基础知识】深拷贝方法

  • 发布:2023-10-10 09:08

js深文案,面试必问,八说,直接上菜~

使用递归进行深复制

let deepClone = (initalObj) => {
const obj = {};
if(typeof initalObj !== 'object'){
          return 初始对象
}
for (const key in initalObj) {
if (类型) initalObj[key] === ' object' ​.isArray(initialObj[key])) {
     //使用map方法返回一个新数组,并递归数组中的元素
    obj[key ] = 初始对象[ key].map(item => 这个 .deepClone(item))
                                                                                                                                                                                                 Obj[key] = 这个.deepClone(initialObj [键]);
    }
    } else if (typeof initalObj[key] === '函数' ? else {
    //基本类型直接返回
    obj[key] = initialObj[key];
   }
    }
    返回 obj;
  }

const obj = {
  a1
   b: {},
  c: { d: {}, g :()=> {} },
  e()=>{},
  f功能 ({}
}
const newObj = deepClone(obj);
newObj.a === obj.a   //正确

newObj.b === obj.b  //false
newObj.c === obj .false  //false
newObj.c.d === obj.c.d  // false
newObj.c.g === obj.c.g  //false
newObj.e === obj.e  //false
newObj.f === obj.f  //假
  • 梯度运行效率低,次数过多的话容易造成栈溢出。
  • 比较方便!兼容性好!

通过JSON序列化实现深拷贝

序列化然后反序列化。

 
功能 克隆(obj{
    var 复制对象= JSON。 stringify(obj),
      //json字符串转json对象
      objClone = JSON.parse(Copyobj);
    返回 objClone;
 }

注意,这种方法容易出现很多问题,实际中并不常用!

  • 如果obj中存在RegExp和Error对象,序列化结果只会得到空对象

  • 如果obj中存在时间对象,则JSON.stringify和JSON.parse的结果中时间只会是字符串的形式。而不是时间对象

  • 如果obj中有function或undefined,序列化结果会丢失function或undefined

  • 如果obj中存在NaN、Infinity和-Infinity,序列化结果将变为null

  • 无法处理函数,无法处理循环引用对象

lodash函数库实现深拷贝

varabj={
a:1,
b:2
}
varcopyobj = lodash .cloneDeep(abj)

这个没什么好说的,就是调用一个库函数而已。原理与第一种相同。

使用jq(extend)方法实现深拷贝

var obj= {
a:10,
b:功能 (){
控制台.log(这个.a)
}
}; var newObj = $.extend( true,{},obj);

这个没什么好说的,就是调用库函数...啊这个

其他补充品

slice() 和 concat()

使用切片和连接方法并不是真正的深复制!

他们只会复制第一层,在第二层及以后,他们只会复制参考地址!

使用方法如下:

  • 对于数组类型,可以使用slice(start, end)方法返回一个新数组。 var arr1 = arr.slice(0);
  • 数组类型也可以使用concat()方法,var arr1 = arr.concat();

object.assign()

var obj1 = { a: 0 , b: { c : 0}};
var obj2 = 对象.分配({}, obj1);

当对象中只有一级属性而没有二级属性时,此方法为深拷贝

如果有多层嵌套怎么办?

 var obj1 = {
a1
b: 2,
c : ['a','b','c']
}
var obj2 = 对象.分配({}, obj1);
obj2.c[1] = 5;
控制台.log(obj1.c); // ["a", 5, "c"]
控制台.log(obj2.c); // ["a", 5, "c"]

可以看到,对于一级对象来说是没有问题的,但是如果对象的属性对应的是其他引用类型,只复制引用,修改的话还是会出现问题。

所以可以看出,当对象中有对象时,这个方法是在次属性之后进行浅拷贝。

总结

原则上,无论嵌套多少层,只有以下两种方法才能实现真正的深拷贝。

  • 自定义递归方法
  • json序列化

但是json序列化容易出现bug,所以在实际编写工具函数时,会使用第一种方法。


相关文章