当前位置:   article > 正文

js深拷贝_undefined" is not valid json

undefined" is not valid json

在JavaScript数据类型可以分为8中:字符串(String)、数字 (Number)、布尔 (Boolean)、空(Null)、未定义(Undefined)、Symbol 、Object、BigInt(任意大的整数)

也可以分为基本数据类型、引用数据类型

基本数据类型:字符串(String)、数字 (Number)、布尔 (Boolean)、空(Null)、未定义(Undefined)、Symbol

-----------存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。

引用数据类型:Object【Object是个大类,function函数、array数组、date日期...等都归属于Object】

-----------存放在堆内存中的对象,在栈内存中存的是一个指针,这个指针指向堆内存一个位置。再从堆内存中取得所需的数据。

区别:

深拷贝:在堆内存中重新开辟一个存储空间,完全克隆一个一模一样的对象。

浅拷贝:不在堆内存中重新开辟空间,只复制栈内存中的引用地址。

本质上两个对象(数组)依然指向同一块存储空间。赋值引用类型的时候肯定不能出现浅拷贝的现象,会对原数据产生影响,那么就要进行深拷贝。

常用的深拷贝方式:

1.JSON.stringify():可以深拷贝的数组和对象,但是不能拷贝undefined和Function类型数据,序列化之后会直接丢失。

  1. var arr = {
  2. name: 'lemon1号',
  3. age: 23,
  4. foods: ['冰淇淋', '水蜜桃'],
  5. friend: {
  6. name: '张三',
  7. age: '22'
  8. },
  9. function(){
  10. console.log("lemon1号的对象")
  11. }
  12. }
  13. //先转为json格式字符,再转回来
  14. var _arr=JSON.parse(JSON.stringify(arr))
  15. _arr.name='lemon2号'
  16. _arr.adress[0]='大西瓜'
  17. console.log("arr为", arr)
  18. console.log("_arr为", _arr)

 2. 封装一个递归方法:这是最保险最推荐的写法。多数第三方库lodash中的cloneDeep()方法底层也是基于的递归。

  1. //使用递归实现深拷贝
  2. function deepClone(obj) {
  3. //变量先置空
  4. let newobj = null;
  5. //obj不能为空,并且是对象或者是数组,null也是object
  6. if (typeof (obj) == 'object' && obj !== null) {
  7. newobj = obj instanceof Array ? [] : {};
  8. //递归进行深度的拷贝
  9. for (var i in obj) {
  10. newobj[i] = deepClone(obj[i])
  11. }
  12. //如果不是对象直接赋值
  13. } else {
  14. newobj = obj;
  15. }
  16. return newobj;
  17. }
  18. //------------------- 使用 ----------------------
  19. let obj = {
  20. name: 'lemon1号',
  21. age: null,
  22. foods: ['冰淇淋', '水蜜桃'],
  23. friend: {
  24. name: '张三',
  25. age: '22'
  26. },
  27. function(){
  28. console.log("lemon1号的对象")
  29. }
  30. }
  31. const newObj = deepClone(obj); //这样就完成了一个对象的递归拷贝
  32. newObj.name = 'lemon2号';
  33. console.log(newObj);

 3.使用扩展运算符:利用了对象的结构赋值特性方法,只能对第一层引用对象进行深拷贝,对于对象中的对象则失效。

  1. var arr = {
  2. name: 'lemon1号',
  3. age: undefined,
  4. foods: ['冰淇淋', '水蜜桃'],
  5. friend: {
  6. name: '张三',
  7. age: '22'
  8. },
  9. function(){
  10. console.log("lemon1号的对象")
  11. }
  12. }
  13. var _arr={...arr} //这样就完成了一个对象一级拷贝
  14. _arr.name='lemon2号'
  15. _arr.friend.name='赵四'
  16. _arr.foods[0]='大西瓜'
  17. console.log("arr为", arr)
  18. console.log("_arr为", _arr)

 4.JQuery的extend()方法进行深拷贝:在JQuery构建的项目中,JQuery自身携带的extend()方法可以进行深拷贝。但是对于undefined类型数据,extend()方法之后会直接丢失。两拷贝对象中有相同的属性名时,后者的值也会覆盖前者的值。

  1. var obj = {
  2. name: 'lemon1号',
  3. age: undefined,
  4. foods: ['冰淇淋', '水蜜桃'],
  5. friend: {
  6. name: '张三',
  7. age: '22'
  8. },
  9. function(){
  10. console.log("lemon1号的对象")
  11. }
  12. }
  13. let _obj= $.extend(true, {}, obj); //这样就完成了一个对象一级拷贝
  14. _obj.name='lemon2号'
  15. _obj.friend.name='赵四'
  16. _obj.foods[0]='大西瓜'
  17. console.log("obj为", obj)
  18. console.log("_obj为", _obj)

总结:在JQuery项目中推荐使用extend()函数,其他项目推荐使用封装的递归函数。

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

闽ICP备14008679号