深拷贝与浅拷贝

深拷贝与浅拷贝

浅拷贝:将原对象或原数组的引用直接赋值给新对象。新对象/新数组只是原对象/原数组的一个引用。
深拷贝:创建一个新对象/数组,将原对象的键/值全部赋值到新对象中,是真值,而非引用。
深拷贝的意义:改变新对象,不影响原对象

堆内存与栈内存

栈内存:存放基本数据类型以及引用类型的地址
堆内存:存放引用类型的真实值

数据结构中的堆与栈

栈:先进后出的数据结构 FIFO

堆:非连续的树形存储结构,根节点是最大的或最小的,用于数据排序

实现单层深拷贝(数组):

方案一:遍历

方案二:array.slice()

  • 拷贝数组为基本数据类型时,为深拷贝
  • 当数组内部存在引用类型时,为浅拷贝
var arr1 = [1,2,3,4,5,6]
var arr2 = arr1.slice()

方案三:array.concat()

  • 拷贝数组为基本数据类型时,为深拷贝
  • 当数组内部存在引用类型时,为浅拷贝
var arr1 = [{name:'jeny'},2,3,4]
var arr2 = [].concat(arr1)
arr1[1].name = 'laowang'
console.log(arr1)   // [{name:'laowang',2,3,4}]
console.log(arr2)   // [{name:'laowang',2,3,4}]

深拷贝对象

方案一:Object.assign(target, source1, source2);

++当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝++

const a = {
    name:'name1',
    age:'age1'
}
const b = {
    name:'name1',
    age:'age1'
}
const c = Object.assign(c,a,b)
方案二:ES6扩展运算符
const obj = {
    name:'name1',
    age:'age1'
}
const {name} = {...obj}
console.log(name)  // name1
方案三:JSON.stringify() && JSON.parse() 深拷贝对象/数组大招,拷贝所有层
function deepClone(obj) {
  let _obj = JSON.stringify(obj);
  let objClone = JSON.parse(_obj);
  return objClone;
}
方案四:递归
function _deepClone(source) {
  let target;
  if (typeof source === 'object') {
    target = Array.isArray(source) ? [] : {}
    for (let key in source) {
      if (source.hasOwnProperty(key)) {
        if (typeof source[key] !== 'object') {
          target[key] = source[key]
        } else {
          target[key] = _deepClone(source[key])
        }
      }
    }
  } else {
    target = source
  }
  return target
}
方案五:通过jQuery的extend方法实现深拷贝
let $ = require('jquery');
let obj1 = {
   a: 1,
   b: {
     f: {
       g: 1
     }
   },
   c: [1, 2, 3]
};
let obj2 = $.extend(true, {}, obj1);
方案六:lodash.cloneDeep()实现深拷贝
let _ = require('lodash');
let obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
let obj2 = _.cloneDeep(obj1);
posted @ 2021-02-15 16:50  南华秋水  阅读(71)  评论(0编辑  收藏  举报