Basic type & reference type

There are two types of data types in ECMAScript:

  • Basic types: undefined, null, Boolean, String, Number, Symbol
  • Reference types: Object, Array, the Date, the Function, the RegExp, etc

Different types of storage:

  • Base type: Base type values occupy a fixed size in memory and are stored in stack memory
  • Reference type: The value of a reference type is an object and is stored in heap memory, while the stack memory stores the variable identifier of the object and the location of the object in heap memory

Different types of replication modes:

  • Basic type: Copying a value of a basic type from one variable to a new variable creates a copy of the value and copies it to the new variable
let foo = 1;
let bar = foo;
console.log(foo === bar); // -> true

// Changing the value of foo does not affect the value of bar
let foo = 233;
console.log(foo); / / - > 233
console.log(bar); / / - > 1
Copy the code
  • Reference type: Copying a value of a reference type from a variable to a new variable is actually copying a pointer so that both variables end up pointing to the same object
let foo = {
  name: 'leeper'.age: 20
}
let bar = foo;
console.log(foo === bar); // -> true

// Changing the value of foo affects the value of bar
foo.age = 19;
console.log(foo); // -> {name: 'leeper', age: 19}
console.log(bar); // -> {name: 'leeper', age: 19}
Copy the code

Deep copy & shallow copy

  • Shallow copy: Only references are copied, and operations on each other affect each other
  • Deep copy: Reallocate memory in the heap. Different addresses, same values, do not affect each other

In general, the main difference between deep and shallow copying is whether references are copied or instances are copied

The implementation of deep and shallow copy

Take a look at whether some of the replication methods provided in native JavaScript are deep copy or shallow copy, and get your hands dirty with deep copy.

Shallow copy

  • Array.prototype.slice()
let a = [1.2.3.4];
let b = a.slice();
console.log(a === b); // -> false

a[0] = 5;
console.log(a); // -> [5, 2, 3, 4]
console.log(b); // -> [1, 2, 3, 4]
Copy the code
  • Array.prototype.concat()
let a = [1.2.3.4];
let b = a.concat();
console.log(a === b); // -> false

a[0] = 5;
console.log(a); // -> [5, 2, 3, 4]
console.log(b); // -> [1, 2, 3, 4]
Copy the code

Array’s slice(),concat() looks like they are deep copies.

let a = [[1.2].3.4];
let b = a.slice();
console.log(a === b); // -> false

a[0] [0] = 0;
console.log(a); // -> [[0, 2], 3, 4]
console.log(b); // -> [[0, 2], 3, 4]
Copy the code

Similarly, concat() is validated:

let a = [[1.2].3.4];
let b = a.concat();
console.log(a === b); // -> false

a[0] [0] = 0;
console.log(a); // -> [[0, 2], 3, 4]
console.log(b); // -> [[0, 2], 3, 4]
Copy the code

In summary, Array’s slice and concat methods are not true deep copies. Array’s layer 1 elements are deep copies, while Array’s layer 2 slice and concat methods copy references. Therefore, Array’s slice and concat methods are shallow copies.

Deep copy

  • JSON. The parse () and JSON. Stringify ()
  1. Json.stringify () : Serializes a JS object to a JSON string
  2. Json.parse () : deserialize the JSON string to a JS object
let obj = {
  name: 'leeper'.age: 20.friend: {
    name: 'lee'.age: 19}};let copyObj = JSON.parse(JSON.stringify(obj));
obj.name = 'Sandman';
obj.friend.name = 'Jerry';
console.log(obj);
// -> {name: "Sandman", age: 20, friend: {age: 19,name: 'Jerry'}}
console.log(copyObj);
// -> {name: "leeper", age: 20, friend: {age: 19,name: 'lee'}}
Copy the code

In summary, json.parse () and json.stringify () are full deep copies.

  • Use recursion to achieve a deep copy of an object or array. Recursive idea: Iterate over the values of all reference types in the attribute until they are of the basic type.
function deepCopy(obj) {
  if(! obj &&typeofobj ! = ='object') {
    throw new Error('error arguments');
  }
  // const targetObj = obj.constructor === Array ? [] : {};
  const targetObj = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    
    // Copy only the object's own properties
    if (obj.hasOwnProperty(key)) {
      if (obj[key] && typeof obj[key] === 'object') {
        targetObj[key] = deepCopy(obj[key]);
      } else{ targetObj[key] = obj[key]; }}}return targetObj;
}
Copy the code