JavaScript中的深浅拷贝

Javascript有五种基本数据类型(也就是简单数据类型),它们分别是:Undefined,Null,Boolean,Number和String,并且基本类型存放在栈内存。还含有一种复杂的数据类型(也叫引用类型)存放在堆内存,就是对象(Object,Array)。 堆内存用于存放由new创建的对象,栈内存存放一些基本的类型的变量和对象的引用变量。

  1. Undefined 其实就是已声明未赋值的变量输出的结果

  2. null 其实就是一个不存在的对象的结果

浅拷贝的意思就是只复制引用(指针),而未复制真正的值

一、数组的深拷贝:

仅适用于对不包含引用对象的一维数组的深拷贝

var arrCopy = arr.concat()   // 或者:[].concat(arr)
var arrCopy = arr.slice(0)
// 如果是对象数组的话,还是会指向同一堆内存地址

同理实现一个数组深拷贝

var deepCopy = (sourceArr) => {
    let targetArr = [];
    for (let i = 0; i < sourceArr.length; ++i) {
    targetArr[i] = sourceArr[i];
  }
  return targetArr;
}

ES6语法实现:

var [...targetArr] = sourceArr;        // 解构赋值

二、对象的深拷贝

  1. 利用递归来实现每一层都重新创建对象并赋值
  2. 利用 JSON 对象中的 parsestringify,function对象,Symbol,RegExp对象是无法通过这种方式深拷贝,当循环引用、重复引用等情况出现就会出现一些问题
  3. ES6扩展运算符实现对象的深拷贝
// 扩展运算符
var {...newObj} = oldObj; //还是只能去做浅拷贝,涉及到嵌套就不行了
var newObj = {...oldObj}

// 递归实现
function deepCopy(source) {
  const targetObj = source instanceof Array ? [] : {};
  for(let key in source) {
    // 判断key对应value的类型,如果是对象,就需要复制
    if(source[key] && typeof source[key] === 'object') {
      targetObj[key] = source[key] instanceof Array ? [] : {};
      targetObj[key] = deepCopy(source[key]);
    } else {
      targetobj[key] = source[key];
    }
  }
  return targetObj;
}

// JSON
const targetObj = JSON.parse(JSON.stringify(sourceObj));

// Object.assign(),用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

参考文章写的很好!

Reference:

  1. https://juejin.im/post/5b5affaef265da0f86543bc9
  2. https://blog.csdn.net/weixin_34004750/article/details/88835370
  3. https://juejin.im/post/5b20c9f65188257d7d719c1c
发表评论 / Comment

用心评论~