当前位置:   article > 正文

深拷贝和浅拷贝的区别及实现方法_深拷贝,浅拷贝区别,实现方式

深拷贝,浅拷贝区别,实现方式

浅拷贝

定义:
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。
如果属性是基本类型,拷贝的就是基本类型的值。
如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

缺陷: 浅拷贝只能实现一层的拷贝,无法进行深层次的拷贝

实现方法:

1.Object.assign()

ES6中拷贝对象的方法,接受的第一个参数是拷贝的目标,剩下的参数是拷贝的源对象(可以是多个)

语法:Object.assign(target, ...sources)

  1. let obj1 = {
  2. name: "王二",
  3. age: 18
  4. }
  5. // Object.assign() 会返回一个新对象
  6. // 这种写法和下面写法实现效果一样
  7. // let obj2 = Object.assign({}, obj1)
  8. let obj2 = {}
  9. Object.assign(obj2, obj1)
  10. obj1.name = '小张';
  11. obj1.age = '25';
  12. console.log(obj1); // {name:"小张", age:25}
  13. console.log(obj2); // {name:"王二", age:18}

 

2.concat()

语法:concat() 合并两个或多个数组,返回一个新数组。原数组不变

  1. let arr = [1,2,3,4];
  2. let newArr = arr.concat()
  3. arr.push(5);
  4. console.log(arr); // [1,2,3,4,5]
  5. console.log(newArr ); // [1,2,3,4]

 

3.扩展运算符

如果对象中的属性都是基本数据类型的话,使用扩展运算符更加方便

  1. let obj1 = {
  2. name: "小李",
  3. age: 18
  4. }
  5. let obj2 = {...obj1}
  6. obj1.name = '小张';
  7. obj1.age = '25';
  8. console.log(obj1, obj2);
  9. let arr = [1, 2, 3]
  10. let newArr = [...arr]
  11. arr[0] = 999
  12. console.log(arr, newArr)

输出结果:


深拷贝

不管原数据中值是什么类型的数据,拷贝后的新数据跟原数据是相互独立,没有关联的

实现方法:

1. 利用json数据和json字符串之间的转换

JSON.stringify() 将对象转换成JSON字符串

JSON.parse() 反序列化将JSON字符串变成一个新的对象

对于日常的开发需求(对象和数组),使用这种方法是最简单和快捷的

缺点: 无法实现对对象中 方法 的拷贝,会显示为undefined

  1. let obj1 = {
  2. name: "小李",
  3. age: 18,
  4. father: {
  5. age: 40
  6. },
  7. fn: function () {
  8. return 123
  9. }
  10. }
  11. let temp = JSON.stringify(obj1)
  12. let obj2 = JSON.parse(temp)
  13. obj1.father.age = 50;
  14. console.log(obj1); // {name:"小李", age:18, father:{age:50},fn()}
  15. console.log(obj2); // {name:"小张", age:25, father:{age:40}}
  16. console.log(obj2.fn) // underfind

 

2.$.extend()

语法: jQuery.extend([deep], target, object1, [objectN])

deep默认为false

  1. // 注意要引入jQuery的CDN才能使用该方法
  2. let obj1 = {
  3. name: "小李",
  4. age: 18,
  5. father: {
  6. age: 40
  7. },
  8. fn: function () {
  9. return 123
  10. }
  11. }
  12. let obj2 = $.extend(true, {}, obj1)
  13. obj1.father.age = 50;
  14. console.log(obj1,obj2);

输出结果:

 

3. 递归

  1. function deepClone(obj) {
  2. // 定义一个对象,用来确定当前的参数是数组还是对象
  3. let objClone = Array.isArray(obj) ? [] : {};
  4. // 判断obj是否存在,且类型是对象。(typeof [] 也是 object
  5. if (obj && typeof obj === "object") {
  6. // 遍历参数的键
  7. for (key in obj) {
  8. // hasOwnProperty() 方法不会检测对象的原型链,只会检测当前对象本身存在该属性时才返回 true,常与for...in使用
  9. // 判断对象是否存在该属性
  10. if (obj.hasOwnProperty(key)) {
  11. // 值是对象就递归
  12. if (obj[key] && typeof obj[key] === "object") {
  13. objClone[key] = deepClone(obj[key]);
  14. } else {
  15. // 基本数据类型 直接赋值
  16. objClone[key] = obj[key];
  17. }
  18. }
  19. }
  20. }
  21. return objClone;
  22. }
  23. let a = {
  24. name: "小李",
  25. age: 18,
  26. father: {
  27. name: "大李",
  28. },
  29. fn: function () {
  30. return 123
  31. }
  32. }
  33. let b = deepClone(a)
  34. a.father.name = "小李他爸"
  35. console.log(a, b);

输出结果:


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/68355
推荐阅读
相关标签
  

闽ICP备14008679号