什么是深/浅拷贝,有哪些实现方式

答案:

JS数据类型分为基本数据类型引用数据类型,基本数据类型保存的是,引用类型保存的是引用地址(this指针)。浅拷贝共用一个引用地址,深拷贝会创建新的内存地址。

浅拷贝方法

  • 直接对象复制

  • Object.assign

深拷贝

  • JSON.stringify转为字符串再JSON.parse

  • 深度递归遍历

 

详细解析:

基本数据类型:string、number、boolean、undefined、null

引用数据类型:object、array、function

浅拷贝,拿人手短,变了;深拷贝,自食其力,不变。

一、浅拷贝

1. 直接对象复制

let a = [0,1,2,3,4],
    b = a;
console.log(a === b);
a[0] = 1;
console.log(a,b);

结果:

2. Object.assign:实现浅拷贝及一层的深拷贝

对象的合并  ES6中的 Object.assign(),第一个参数必须是个空对象。

Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

注意点!严格来说,Object.assign()  既不是深拷贝,也不是浅拷贝——而是第一级属性深拷贝,第一级以下的级别属性浅拷贝

let obj1 = {
   a: { b: 1},
   c: 2
}
let obj2 = Object.assign({},obj1)
obj2.a.b = 3;  //第二层,obj1变了,是浅拷贝
obj2.c = 3;  //第一层,obj1不变,是深拷贝
console.log(obj1);  
console.log(obj2); 

结果:

二、深拷贝

1. JSON.stringify转为字符串再JSON.parse

JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象

function deepClone(obj) {
    let _obj = JSON.stringify(obj)
    let objClone = JSON.parse(_obj)
    return objClone
}

let a = [0, 1, [2, 3], 4]
let b = deepClone(a)
a[0] = 1
a[2][0] = 1
console.log(a)  // [1,1,[1,3],4]
console.log(b)  // [0,1,[2,3],4]

结果:

缺点:当值为undefined、function、symbol 会在转换过程中被忽略

2. 深度递归遍历

基本思路:判断obj 是基本类型就简单赋值,对象(数组)的话 ,创建一个空[ ](obj是对象)或空{ }(obj是对象),再判断obj的属性有没有对象(数组),有递归调用,没有简单赋值,直到全部赋值完毕,返回赋值后的objClone

function deepClone(obj) {
  let objClone = Array.isArray(obj) ? [] : {} //根据类型制造一个新的数组或对象 Array.isArray判断是否是数组
  if (obj && typeof obj === 'object') {
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        // 判断obj子元素是否为对象,如果是对象,递归复制
        if (obj[key] && typeof obj[key] === 'object') {
          objClone[key] = deepClone(obj[key])
        // 如果是基本数据类型,只是简单的复制
        } else {
          objClone[key] = obj[key]
        }
      }
    }
  }
  return objClone
}
 
let a = [1,2,3,4]
let b = deepClone(a)  
a[0] = 2 
console.log(a)  // [2,2,3,4]
console.log(b)  // [1,2,3,4]

结果:

3. jquery实现深拷贝
jquery 提供一个 $.extend 可以用来做深拷贝;

var array1 = [1,2,3,4];
var array2 = $.extend(true,[],array1); // true为深拷贝,false为浅拷贝
console.log(array1 === array2);  // false
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值