深拷贝的方法

1.JSON转换

  1. var targetObj = JSON.parse(JSON.stringify(copyObj))
  2. let arr4 = JSON.parse(JSON.stringify(arr))

缺点:
(1)如果对象里有函数,函数无法被拷贝下来
(2)无法拷贝copyObj对象原型链上的属性和方法
(3)当数据的层次很深,会栈溢出

2.普通递归函数

  1. function deepCopy( source ) {
  2. if (!isObject(source)) return source; //如果不是对象的话直接返回
  3. let target = Array.isArray( source ) ? [] : {} //数组兼容
  4. for ( var k in source ) {
  5. if (source.hasOwnProperty(k)) {
  6. if ( typeof source[ k ] === 'object' ) {
  7. target[ k ] = deepCopy( source[ k ] )
  8. } else {
  9. target[ k ] = source[ k ]
  10. }
  11. }
  12. }
  13. return target
  14. }
  15. function isObject(obj) {
  16. return typeof obj === 'object' && obj !== null
  17. }

缺点:
(1)无法保持引用
(2)当数据的层次很深,会栈溢出

3.防栈溢出函数

  1. function cloneLoop(x) {
  2. const root = {};
  3. // 栈
  4. const loopList = [
  5. {
  6. parent: root,
  7. key: undefined,
  8. data: x,
  9. }
  10. ];
  11. while(loopList.length) {
  12. // 深度优先
  13. const node = loopList.pop();
  14. const parent = node.parent;
  15. const key = node.key;
  16. const data = node.data;
  17. // 初始化赋值目标,key为undefined则拷贝到父元素,否则拷贝到子元素
  18. let res = parent;
  19. if (typeof key !== 'undefined') {
  20. res = parent[key] = {};
  21. }
  22. for(let k in data) {
  23. if (data.hasOwnProperty(k)) {
  24. if (typeof data[k] === 'object') {
  25. // 下一次循环
  26. loopList.push({
  27. parent: res,
  28. key: k,
  29. data: data[k],
  30. });
  31. } else {
  32. res[k] = data[k];
  33. }
  34. }
  35. }
  36. }
  37. return root;
  38. }

优点:
(1)不会栈溢出
(2)支持很多层级的数据

  1. function copyObject(orig) {
  2. var copy = Object.create(Object.getPrototypeOf(orig));
  3. copyOwnPropertiesFrom(copy, orig);
  4. return copy;
  5. }
  6. function copyOwnPropertiesFrom(target, source) {
  7. Object
  8. .getOwnPropertyNames(source)
  9. .forEach(function (propKey) {
  10. var desc = Object.getOwnPropertyDescriptor(source, propKey);
  11. Object.defineProperty(target, propKey, desc);
  12. });
  13. return target;
  14. }
  15. var obj = {
  16. name: 'Jack',
  17. age: '32',
  18. job: 'developer'
  19. };
  20. var obj2 = copyObject(obj);
  21. console.log(obj2);
  22. obj.age = 39;
  23. obj.name = 'Tom';
  24. console.log(obj);
  25. console.log(obj2);