The assignment

  1. When we assign an object to a new object, we assign the address of the object in the stack, not the data in the heap so that after the assignment, both objects point to the same storage space. Whenever an object changes, it’s actually the data in the heap that’s changed
let a = {
name: 'a'.like: ['eat']}let b = a

b.name = 'b'
b.like[0] = 'sleep'
console.log('a', a)
console.log('b', b)
Copy the code

When we assign a variable to another variable, we add a variable to the stack memory and assign a value. The two do not affect each other

 let c = 1
 let d = c
 d = 2
 console.log(c) //c1
 console.log(d) / / 2
Copy the code

Shallow copy

Shallow copy copies only Pointers to an object, not the object itself, and the old and new objects still share the same memory. But deep copy will create another identical object, the new object and the original object do not share memory, modify the new object will not change to the original object.

Using the {… } implement copy. Note that this is a copy, not to distinguish between shallow or deep

If it is a reference type and there is only one layer of objects, that layer is a deep copy. Before and after the copy, the basic type of the object does not affect each other. If the object is a reference type and there are more than two nested objects, the nested object is a shallow copy. Nested object, a reference to the nested object that is copied. Before and after the copy, the nested object data affects each other, and the one-layer objects do not affect each other.

let obj = {
    name: 1.address: {
        x: 1}}letd = { ... obj } d.name =4 // One layer of deep copy, each other
d.address.x = 'x' // Two layers, copy things address, affect each other
console.log('Shallow copy', obj){name: 1, address: {x: 'x'}}
console.log('Shallow copy', d){name: 4, address: {x: 'x'}}
Copy the code
  • Modify the d.name of a layer object. You’ll find that it doesn’t affect each other.Because deep copy
  • Modify the d.address.x of the nested object. You will find that the interaction,Because it's a shallow copy

Shallow copy implementation

function shallowCopy (obj) {
  let target = {}
  for (let k in obj) {
    if (obj.hasOwnProperty(i)) { // Do not iterate over properties on its prototype chain
      target[i] = obj[i] 
    }
  }
  return target
}
Copy the code

One problem with for-in loops is that they not only iterate over the instance properties of the object, but also over properties inherited from the prototype chain, filtering out the instance properties of the object with hasOwnProperty

Deep copy

In the heap memory, a new area is opened to store objects, and the children of objects are copied recursively. Before and after the copy, the two objects do not affect each other

function deepClone(obj, hash = new Map(a)) {
    if (obj == null) return obj // If null and undefined, no operation is performed
    if (obj instanceof Date) return new Date(obj)
    if (obj instanceof RegExp) return RegExp(obj)
    // If the value is normal, no copy is required
    if (typeofobj ! = ='object') return obj
    // If it is an object, make a deep copy
    if (hash.get(obj)) return hash.get(obj)
    let cloneObj = new obj.constructor
    hash.set(obj, cloneObj)
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            cloneObj[key] = deepClone(obj[key], hash)
        }
    }
    return cloneObj
}
let obj = {
    name: 1.address: {
        x: 1}}let d = deepClone(obj)
d.address.x = 4
console.log(obj, d)//{ name: 1, address: { x: 1 } } { name: 1, address: { x: 4 } }
Copy the code
  • WeakMap is required if circular references occur

Shortcut for shallow copy

  1. Object.assign({},) // One layer is a deep copy, and more than two layers are shallow copies
  2. {… } // One layer is a deep copy, and two or more layers are shallow copies
  3. loadsh

Deep copy

  1. JSON.parse(JSON.stringify())
  2. lodash

JSON.parse(JSON.stringify())

  1. Serialize the JS object to a JSON string, and then deserialize it to the original JS object
  2. If obj has a function called undefined, the serialization result will lose the function or undefined.
  3. If there are RegExp or Error objects in obj, serialization will result in empty objects
  4. If obj has a time object in it, serialization will result in a string

5. Only enumerable free properties of objects can be serialized. If objects in obj are generated by constructors, constroter will be lost after being copied

conclusion

  • The implementation of assignment is just one=, while the shallow copy isCreate a new {}, then you can see that the assignment points to the same object as the original data, while the shallow copy points to a different object.
  • A copy is a copy of an object (reference data type), so if you’re a primitive data type, use assignment
  • There are a couple of points in the deep copy, which is nice, and one is for null and undefined, because null == nudefined, so one of them is fine
  • Use new obj.constructor to check whether it is an array or an object. It will return the data you want to copy, and can get the type passed in. So that’s a lot easier than this line of code array.isarray (obj)? [] : {}
  • If a circular reference occurs, use new WeakMap.