preface

What is a copy? This refers to js variable assignment

How to distinguish between shallow and deep copies? Change the value of variable A to variable B, where variable A, variable B is affected (shallow copy), not affected (deep copy)

To understand the depth of the copy, the first js data type start, because in JS basic type and reference type value storage way is different, assignment processing is not

Basic types of

Boolean Number// Has several special values including NaN (meaning "not a Number", +Infinity, -infinity, -0 String Null undefined Symbol(ES6+) BigInt(ES11+)Copy the code

Basic types are immutable, and you cannot add attributes and methods to them (adding them does not report an error, but does not work)

Reference types

Object // Contains Array, Function, Date, RegExp, and ErrorCopy the code

Reference types are mutable, and you can add or remove properties and methods to base types

Assignment principle

let num1=10
let obj1={name:'obj1'}

let num2=num1
let obj2=obj1

num2=20
obj2.name='obj2'

console.log(num1)/ / 10
console.log(obj1.name)//obj2
Copy the code

Light and dark copying occurs because JS treats primitive and reference types differently.

  1. Primitive types refer to simple data segments

  2. A reference type refers to the address of an object stored in heap memory

  3. JS does not allow us to directly manipulate the address in memory, that is, we cannot manipulate the memory space of the object, so we only manipulate the reference of the object.

Summary: The same is true when copying. If we copy a value of a primitive type, we create a new value and store it in the location of the new variable. If we copy a reference type, we also copy the value of the variable into the new variable space, but instead of copying the object itself, we copy a pointer to the object. So when we copy the reference type, the two variables actually refer to the same object, so changing one object affects the other.

Shallow copy

Copy the value or memory address of the first layer property

  1. Lodash provided_.clone()
  2. Object.assign()andObject.create()
  3. {... obj}
  4. Handwritten shallow copy
function shallowClone(sourceObj={}){
	let targetObj=Array.isArray(sourceObj)? [] : {};let copy;
   	for(var key in sourceObj){
    	copy=sourceObj[key];
        targetObj[key]=copy;
    }
    return targetObj
}
Copy the code

Deep copy

Make a full copy of an object with the same value but a different memory address

  1. Lodash provided_.cloneDeep()
  2. JSON.parse(JSON.stringify())But there are many side effects
  1. Undefined will lose this property,
  2. If the value is a function, this property will be lost,
  3. The value is of type Date and toJSON() is called,
  4. The value is of type RegExp, which becomes {},
  5. An error will be reported for circular references
  1. Handwritten deep copy
function deepClone(obj, cache = new WeakMap(a)) {
  if(! objinstanceof Object) return obj
  // Prevent circular references
  if (cache.get(obj)) return cache.get(obj)
  // Support functions
  if (obj instanceof Function) {
    return function () {
      return obj.apply(this.arguments)}}// Support date
  if (obj instanceof Date) return new Date(obj)
  // Regular objects are supported
  if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags)

  // Arrays are special objects whose key is a numeric index
  const res = Array.isArray(obj) ? [] : {}
  // Cache the copy object to handle cyclic references
  cache.set(obj, res)

  Object.keys(obj).forEach((key) = > {
    if (obj[key] instanceof Object) {
      res[key] = deepClone(obj[key], cache)
    } else {
      res[key] = obj[key]
    }
  });
  return res
}
Copy the code

reference

Segmentfault.com/a/119000001…