浅复制和深复制的区别?

即最大的区别在于,复制过程中的值是否为引用传值。

什么情况下是引用传递呢?

众所周知,JS 中现在有七个不同类型:

其中基本类型为传值,引用类型(Object)则为引用传递。

浅复制 VS 深复制

什么是浅复制和深复制。

var target = 1 //原始类型
var result = target1 //深->值传递
target = 2
console.log(target, result) // 1 2

//浅复制
var target = { a: 1 } //Object
var result = target //浅->引用传递
target.a = 2
console.log(target, result) //{a: 2} {a: 2}

//深复制(基本实现)
var target = { a: 1 }
var result = { a: target.a } //转化为基本类型 1
target.a = 2
console.log(target, result) //{a: 2} {a: 1}

Object 浅拷贝

var target = { a: 1, b: { c: 'c' } }

var result = Object.assign({}, target)
target.a = 2
console.log(target, result)
//{a: 2, b: {c:"c"}} {a: 1, b: {c:"c"}}

//由于 `Object,assign(..)` 是使用 = 进行的赋值操作
//当源对象的属性值是指向对象的引用时,也只拷贝引用值。
target.b.c = 2
console.log(result) //{a: 1, b: {c:"c"}}

深拷贝

//JSON 安全
JSON.parse(JSON.stringify(target))

// 递归遍历
const deepCopy = (value, map = new WeakMap()) => {
  if (!value || typeof value !== "object") {
    return value;
  }
  
  // ... other case

  //date regexp set map ...
  if (getType(value) !== "object" && getType(value) !== "array") {
    return new value.constructor(value);
  }

  if (map.get(value)) return value;
  map.set(value, value.constructor);

  const result = Array.isArray(value) ? [] : {};
  for (const key in value) {
    result[key] = deepCopy(value[key], map);
  }

  return result;
};

const getType = (value) => {
  const raw = Object.prototype.toString.call(value);
  return raw.substring("[object ".length, raw.length - 1).toLowerCase();
};