js 深拷贝和浅拷贝

说到深拷贝和浅拷贝,首先我们要了解内存中 堆和栈 的概念
  • 堆 内存中存放引用数据类型的区域,其指针地址存放在 栈 中
  • 栈 内存中存放基本数据类型的区域
    image
深拷贝和浅拷贝都是对引用类型而言, 接下来在了解一下 深拷贝和浅拷贝的概念,
  • 深拷贝 在堆内存中新开辟一块区域,用于存放引用类型数据
  • 浅拷贝 拷贝栈内存中引用类型的指针地址
浅拷贝
// 浅拷贝 只是拷贝了 引用类型 的指针地址
let obj = {
    name:'wg',
    age:18
}
let obj2 = obj;
obj2.age = 20
console.log(obj,'obj')
console.log(obj2,'obj2')
//{name: 'wg', age: 20} 'obj'
//{name: 'wg', age: 20} 'obj2'

// obj2 只是赋值了 obj的指针地址,其实 obj 和 obj2 指向同一个对象
深拷贝
// 在堆内存中 新开一块内存,用于存储 拷贝的引用类型数据
let obj = {
    name:'wg',
    age:18
}
let obj2 = JSON.parse(JSON.stringify(obj))
obj2.age = 20
console.log(obj,'obj')
console.log(obj2,'obj2')
// {name: 'wg', age: 18} 'obj'
// {name: 'wg', age: 20} 'obj2'

// JSON.Stringify(obj) 先把引用对象转换成基本数据类型
// JSON.parse(stringObj) 再把字符串对象 解析成 对象,会单独开辟一块内存,从而实现深拷贝

------手写深拷贝函数------
//JSON.parse 能深拷贝 array json 类型,对于其他引用类型则根据需要进行 手写实现
  function deepcopy(obj) {
    let result;
    // 如果是数组
    if (Object.prototype.toString.call(obj) == '[object Array]') {
      result = []
      for (let i in obj) {
        result.push(deepcopy(obj[i]))
      }
    } else if (Object.prototype.toString.call(obj) == '[object Object]') {
      result = {}
      for (let i in obj) {
        console.log(i)
        result[i] = deepcopy(obj[i]);
      }
    } else if (Object.prototype.toString.call(obj) == '[object Function]') {
      result = new Function('return ' + obj.toString())()
    } else {
      result = obj
    }
    return result
  }
// 上述实现了 对数组 对象 和 函数的深拷贝,对于其他引用类型(正则 日期)的数据,可以参考 lodash 的实现方式
posted @ 2021-10-11 13:16  一晃十年  阅读(42)  评论(0编辑  收藏  举报
业精于勤荒于嬉 行成于思毁于随