js 基础之 深浅拷贝与赋值

什么是深/浅拷贝?和赋值的区别?实现的方案?

浅拷贝:基本数据类型和引用数据类型表现形式不一样,基本数据类型指针指向栈内存,拷贝的是值,引用数据类型指针指向的虽然也是栈内存,但是拷贝的是内存地址,这个地址指向堆内存中的值。所以引用数据类型共用一片内存空间,会造成其中一个对象改变了地址,另一个对象也随之改变。

深拷贝:深拷贝会从堆内存自己开辟一片新的内存区域。

赋值:基本数据类型和引用数据类型拷贝的都是地址

举例:

赋值:修改赋值后的对象b的非对象属性,也影响原对象a的非对象属性;修改赋值后的对象b的对象属性,也影响原对象a的对象属性

浅拷贝:修改赋值后的对象b的非对象属性,不会影响原对象a的非对象属性;修改赋值后的对象b的对象属性,却影响原对象a的对象属性

深拷贝:改赋值后的对象b的非对象属性,不会影响原对象a的非对象属性;修改赋值后的对象b的对象属性,也不会影响原对象a的对象属性

实现方案:

浅拷贝

object.assigin()    concant     slice   展开运算符... 

深拷贝:  

1.乞丐版 JSON.stringfy

function Obj() {
  this.func = function () {
    alert(1)
  }
  this.Obj = {a:1};
  this.arr = [1,2,3]; 
  this.und = undefined;  // 消失
  this.reg = /123/ //{}
  this.data = new Date(0); // 字符串
  this.nan = NaN // null
  this.infinity = Infinity;  //null 
  this.sym = Symbol(1) // 消失
}

let Obj1 = new Obj();
Object.defineProperty(Obj1,'innumberable',{
  enumerable:false,
  value:'innumberable'
});  //无

console.log('obj1',Obj1);

let str = JSON.stringify(Obj1)
let Obj2 = JSON.parse(str)
console.log('obj2',Obj2);

 拷贝的对象如果有 函数 undefind symbol 这几种类型 经过序列化后键值对会消失

拷贝data引用类型会变成字符串

无法拷贝 不可枚举属性/对象原型链

拷贝regexp 引用类型会变成空对象

对象中含有NAN , infinity 以及 -infinity ,json序列化的结果会变成null

无法拷贝循环引用

2.基础版: 手写递归

var obj = {
  name: 'xiaoming',
  age: 10,
  arr: [1, 2, 3],
  a: {
    b: 'xiaoli'
  },
  und : undefined,  
  reg :/123/ ,
  data :new Date(0), 
  nan : NaN ,
  infinity : Infinity,  
  sym :Symbol(1), 
  func :function () {
    alert(1)
  }
}
Object.defineProperty(obj,'innumberable',{
  enumerable:false,
  value:'innumberable'
});  //无

function deepClone (obj) {
  let cloneObj = Array.isArray(obj) ? [] : {}
    for (const key in obj) {
      if (obj && typeof obj[key] === 'object') {   
          cloneObj[key] = deepClone(obj[key])
      } else {
         cloneObj[key] = obj[key]
      }  
    }
  return cloneObj
}

var obj1 = deepClone(obj)
obj1.a.b= 'xiaoli2'
console.log(obj1,'obj1');
console.log(obj,'obj');

 不能拷贝symbol 以及不可枚举属性.  ????

这种方法只针对普通引用类型的值做递归处理(日期函数 function 正则 错误对象)

对象的属性里面成环,即循环引用没有解决

3.改进版:解决基础版的问题

symbol 以及不可枚举属性用Reflect.ownKeys

参数为data 以及 regex类型 返回新实例

object的getOwnPropertyDescriptors 所有属性以及对应特性,Object的create方法创建一个新的对象并且继承传入原对象的原型链

weakmap,弱引用类型防止内存泄漏,如果有循环,引用直接返回weakMap存储的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值