Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

Shallow copy and deep copy is a popular interview question. Today we will summarize what shallow copy methods are available, as well as their advantages and disadvantages

First, what is a shallow copy

Create a new object of your own to accept the object values you want to copy or reference again. If the object property is a primitive data type, the value of the primitive type is copied to the new object. But if the property is a reference data type, the copy is the address in memory, and if one object changes the address in memory, the other object must be affected.

Object.assign

Object.assign is a method of Object. This method can be used to merge JS objects. The first argument to this method is the target object to copy, followed by the source object (or multiple sources) to copy.

const obj = {};
const source = {
  name: 'nordon'.info: {
    age: 18}};Object.assign(obj, source);
console.log(obj); // {name: 'nordon', info: {... }}
Copy the code

This is very convenient to complete the money copy, then you can modify the data

source.info.age = 20;
console.log(obj);
console.log(source);
Copy the code

After the modification, the age of both obj and source is 20, satisfying the shallow copy definition

Note:

  • It does not copy the object’s inherited properties;
  • It does not copy the object’s non-enumerable properties;
  • Properties of type Symbol can be copied.
const obj = {};

const source = {
  name: 'nordon'.symbol: Symbol()
};

Object.defineProperty(source, 'innumerable', {value:'innumerable'.enumerable:false
});

Object.assign(obj, source);
console.log(obj); // {name: 'nordon', symbol: Symbol()}
Copy the code

Common inherited attributes such as toString are not shallow copied by Object.assign

Extended operator

Shallow copies can also be made using extended operators

const source = {
  name: 'nordon'.info: {
    age: 18}};constobj = {... source};Object.assign(obj, source);
source.info.age = 20;
console.log(obj);
console.log(source);
Copy the code

The above code is the same as using object. assign, with the same precautions. They can be converted to each other

Array.prototype.concat

When concatenating an array with a reference type, you need to modify the attributes of the elements in the original array, because this will affect the concatenated array after copying

const arr = [1.2, {name: 'nordon'}];
const newArr = arr.concat();
newArr[2].name = 'wy';
console.log(arr); 
console.log(newArr);
Copy the code

Arr and newArr index 2 are changed from **{name: ‘nordon’} to {name: ‘wy’}**

Array.prototype.slice

The slice method of arrays is actually a shallow copy with fewer scenarios, like cancat

const arr = [1.2, {name: 'nordon'}];
const newArr = arr.slice();
newArr[2].name = 'wy';
Copy the code

Use third-party libraries & manual implementation

There are several libraries of tools that can be used to implement shallow copies. Lodash, for example, provides the Clone method for shallow copies

Finally, let’s implement a shallow copy function ourselves

According to the above shallow copy definition, it can be clearly known that the core point of shallow copy is:

  • Direct copy of data for underlying data types
  • For reference type data, copy only the properties of the layer 1 object, creating a new address to store it (important difference between deep copy and shallow copy)

Now go straight to the code:

const clone = (target) = > {
  // If it is a reference type
  if (typeof target === "object"&& target ! = =null) {
    // Determine whether it is data or object, and initialize a data for it
    const cloneTarget = Array.isArray(target) ? [] : {};
    
    // for in can iterate over a number of objects
    for (let prop in target) {
      if(target.hasOwnProperty(prop)) { cloneTarget[prop] = target[prop]; }}return cloneTarget;
  } else {
    // Base type returns directly
    returntarget; }};Copy the code