资讯专栏INFORMATION COLUMN

深入JavaScript中深拷贝和浅拷贝

TalkingData / 1968人阅读

摘要:深拷贝和浅拷贝问题的本质还是不同数据类型的存储方式差异,尤其是引用数据类型的特殊。

深拷贝和浅拷贝问题的本质还是不同数据类型的存储方式差异,尤其是引用数据类型的特殊。

现分别对赋值、浅拷贝、深拷贝做深入研究:

1.赋值

原理:直接将对象指针直接赋值给另一个变量

代码

</>复制代码

  1. let developer = {
  2. title: "Frontend",
  3. basic: {
  4. html: "5",
  5. css: "3",
  6. js: "es6"
  7. },
  8. frameworks: ["React", "Vue", "AngularJS"],
  9. summary: function(){
  10. console.log("I am FE developer");
  11. }
  12. };
  13. let newDeveloper = developer;
  14. console.log(newDeveloper);
  15. //基本类型:改变原对象
  16. newDeveloper.title = "Frontend Leader";
  17. console.log(developer.title); // Frontend Leader
  18. //对象:改变原对象
  19. newDeveloper.basic.http = "2.0";
  20. console.log(developer.basic.http); // 2.0
  21. newDeveloper.basic.js = "es5";
  22. console.log(developer.basic.js); // es5
  23. //数组:改变原对象
  24. newDeveloper.frameworks.push("Angular");
  25. console.log(developer.frameworks); // [ "React", "Vue", "AngularJS", "Angular" ]
  26. //函数:改变原对象
  27. newDeveloper.summary = function () {
  28. console.log("I like FE development");
  29. };
  30. developer.summary(); // I like FE development
2.浅拷贝

原理:遍历对象的每个属性进行逐个拷贝

实现方式

方式1:遍历并复制

方式2:Object.assign()

代码

</>复制代码

  1. let developer = {
  2. title: "Frontend",
  3. basic: {
  4. html: "5",
  5. css: "3",
  6. js: "es6"
  7. },
  8. frameworks: ["React", "Vue", "AngularJS"],
  9. summary: function(){
  10. console.log("I am FE developer");
  11. }
  12. };
  13. /*
  14. * 方式1:逐个复制
  15. *
  16. * */
  17. function cloneInShallow(source) {
  18. let target = {};
  19. for (prop in source){
  20. target[prop] = source[prop];
  21. }
  22. return target
  23. }
  24. let newDeveloper = cloneInShallow(developer);
  25. /*
  26. * 方式2:Object.assign()
  27. *
  28. * */
  29. // let newDeveloper = Object.assign({}, developer);
  30. console.log(newDeveloper);
  31. //基本类型:不改变原对象
  32. newDeveloper.title = "Frontend Leader";
  33. console.log(developer.title); // Frontend
  34. // 对象:改变原对象
  35. newDeveloper.basic.http = "2.0";
  36. console.log(developer.basic.http); // 2.0
  37. newDeveloper.basic.js = "es5";
  38. console.log(developer.basic.js); // es5
  39. //数组:改变原对象
  40. newDeveloper.frameworks.push("Angular");
  41. console.log(developer.frameworks); // [ "React", "Vue", "AngularJS", "Angular" ]
  42. //函数:不改变原对象
  43. newDeveloper.summary = function () {
  44. console.log("I like FE development");
  45. };
  46. developer.summary(); // I am FE developer
3.深拷贝

原理:使用递归,遍历每一个对象属性进行拷贝

实现方式

方式1: 纯手工打造回调函数

方式2: JSON.parse(JSON.stringify(obj))

方式3: 借助jQuery

方式4: 借助lodash

代码

</>复制代码

  1. let developer = {
  2. title: "Frontend",
  3. basic: {
  4. html: "5",
  5. css: "3",
  6. js: "es6"
  7. },
  8. frameworks: ["React", "Vue", "AngularJS", {node: "express"}],
  9. summary: function(){
  10. console.log("I am FE developer");
  11. }
  12. };
  13. /*
  14. * 方式1: 纯手工打造
  15. * */
  16. function cloneInDeep(source) {
  17. if(source && typeof source === "object"){
  18. let target = {};
  19. for (let prop in source){
  20. let value = source[prop];
  21. if(Array.isArray(value)){
  22. let newArray = [];
  23. value.forEach(function (item, index) {
  24. if(Array.isArray(item) || Object.getPrototypeOf(item) === Object.prototype){
  25. newArray.push(cloneInDeep(item))
  26. }else{
  27. newArray.push(item)
  28. }
  29. });
  30. target[prop] = newArray;
  31. }else if(Object.getPrototypeOf(value) === Object.prototype){
  32. target[prop] = cloneInDeep(value);
  33. }else{
  34. target[prop] = value;
  35. }
  36. }
  37. return target
  38. }else{
  39. throw new Error("source is not object!")
  40. }
  41. }
  42. let newDeveloper = cloneInDeep(developer);
  43. /*
  44. * 方式2: JSON.parse(JSON.stringify(obj))
  45. * 弊端:会抛弃对象的constructor
  46. * 适用:能够被json直接表示的数据结构,对象中只包含number、string、boolean、array、扁平对象
  47. * 不适用:含有function、regexp
  48. * */
  49. // let newDeveloper = JSON.parse(JSON.stringify(developer));
  50. /*
  51. * 方式3: jQuery
  52. * */
  53. let $ = require("jquery");
  54. // let newDeveloper = $.extend({}, developer);
  55. /*
  56. * 方式4: lodash
  57. * */
  58. let _ = require("lodash");
  59. // let newDeveloper = _.cloneDeep(developer);
  60. console.log(newDeveloper);
  61. //基本类型:不改变原对象
  62. newDeveloper.title = "Frontend Leader";
  63. console.log(developer.title); // Frontend
  64. // 对象:不改变原对象
  65. newDeveloper.basic.http = "2.0";
  66. console.log(developer.basic.http); // undefined
  67. newDeveloper.basic.js = "es5";
  68. console.log(developer.basic.js); // es6
  69. //数组:不改变原对象
  70. newDeveloper.frameworks.push("Angular");
  71. console.log(developer.frameworks); // [ "React", "Vue", "AngularJS" , { node: "express" } ]
  72. newDeveloper.frameworks[3].node = "koa";
  73. console.log(developer.frameworks); // [ "React", "Vue", "AngularJS" , { node: "express" } ]
  74. //函数:不改变原对象
  75. newDeveloper.summary = function () {
  76. console.log("I like FE development");
  77. };
  78. developer.summary(); // I am FE developer
涉及的知识点:

数据类型及存储机制

for...in...遍历,枚举属性

递归

对象和数组的判断

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95365.html

相关文章

  • 浅谈JavaScript 中深拷贝实现的方法

    摘要:相信人很多学习的过程中都踩了深拷贝和浅拷贝的坑,深拷贝和浅拷贝的区别我就不再赘述了,今天我来写一下我自己实现深拷贝的各种方法。中的深拷贝也是用类似方法实现。 相信人很多学习js的过程中都踩了深拷贝和浅拷贝的坑,深拷贝和浅拷贝的区别我就不再赘述了,今天我来写一下我自己实现深拷贝的各种方法。 比较简单的拷贝方式可以借用浏览器的Json对象去实现,先把对象转化为json字符串,在解析回对...

    Vicky 评论0 收藏0
  • JS里深拷贝和浅拷贝的释义

    摘要:本文解释中深拷贝和浅拷贝的区别。深拷贝深拷贝指递归的复制对象的属性给新对象。有些时候一层的深拷贝被认为是浅拷贝,比如的值是一个对象,浅拷贝出来的新对象直接引用了原对象的对象,所以也会相互影响的。 本文解释javascript中深拷贝和浅拷贝的区别。 浅拷贝/Shallow Copy 浅拷贝指拷贝了引用值。 var original = {prop1 : Prop1, prop2 : p...

    zollero 评论0 收藏0
  • 一篇文章理解JS数据类型、深拷贝和浅拷贝

    摘要:接下来我们进入正片数据类型六种基本数据类型布尔值,和一个表明值的特殊关键字。一种数据类型,它的实例是唯一且不可改变的。在中是没有方法是可以改变布尔值和数字的。参考资料深拷贝浅拷贝 前言 笔者最近整理了一些前端技术文章,如果有兴趣可以参考这里:muwoo blogs。接下来我们进入正片: js 数据类型 六种 基本数据类型: Boolean. 布尔值,true 和 false. nu...

    EddieChan 评论0 收藏0
  • 一篇文章理解JS数据类型、深拷贝和浅拷贝

    摘要:接下来我们进入正片数据类型六种基本数据类型布尔值,和一个表明值的特殊关键字。一种数据类型,它的实例是唯一且不可改变的。在中是没有方法是可以改变布尔值和数字的。参考资料深拷贝浅拷贝 前言 笔者最近整理了一些前端技术文章,如果有兴趣可以参考这里:muwoo blogs。接下来我们进入正片: js 数据类型 六种 基本数据类型: Boolean. 布尔值,true 和 false. nu...

    enda 评论0 收藏0

发表评论

0条评论

TalkingData

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<