Basic types and reference types

Data types in ECMAScript are divided into:

  • Basic types: String, Number, Boolean, Symbol, NULL, undefined
  • Reference types: Object, Array, Date, RegExp, Function, 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 stored in heap memory, while the stack memory holds the variable identifier of the object and the storage address of the object stored 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

Second, the copy

  • Shallow copy (one layer) : Only references are copied, and operations on each other affect each other
  • Deep copy (multiple layers) : Reallocation of memory in the heap, different addresses, the same value, do not affect each other

First of all, deep copy and shallow copy are only for complex objects such as Object and Array. In simple terms, shallow replication only copies the properties of one level of objects, while deep replication recursively copies all levels.

2.1 shallow copy

2.1.1 Object. The assign

// Use object.assign
// Using object.assign (), you can get all the properties of another Object without inheritance. Quick and easy to use.
// The object. assign method copies only the enumerable properties of the source Object and the properties of the Object itself.
let obj = { a:1.arr: [2.3]};
let res = Object.assign({}, obj)

console.log(res.arr === obj.arr); // true, which points to the same reference
console.log(res === obj); // false
Copy the code

2.1.2 Extension operators

// Use the extension operator (...) To solve the
let obj = { a:1.arr: [2.3]};
letres = {... obj};console.log(res.arr === obj.arr); // true, which points to the same reference
console.log(res === obj); // false
Copy the code

2.1.3 Shallow copy native implementation

const shallowCopy = (sourceObj) = > {
  if (typeofsourceObj ! = ='object') return;
  let newObj = sourceObj instanceof Array ? [] : {};
  
  for(let key in sourceObj){ 
    if(sourceObj.hasOwnProperty(key)) {
      // Copy only the attributes of the element itself, not those on the stereotype chainnewObj[key] = sourceObj[key]; }}return newObj;
}

let obj = { a:1.arr: [2.3]};
let res = shallowCopy(obj);
console.log(res.arr === obj.arr); // true, which points to the same reference
console.log(res.a === obj.a); // false
Copy the code

Arr and shallowobj. arr point to the same memory location. The following is a sketch of how this is done.

2.2 deep copy

2.2.1 JSON serialization

  • Json.stringify () : Serializes a JS object to a JSON string
  • Json.parse () : deserialize the JSON string to a JS object
Parse (json.stringify (object))
let a = {
    age: 1.jobs: {
        first: 'FE'}}let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
Copy the code

But there are limitations to this approach:

  1. Ignores undefined
  2. Cannot serialize functions (functions are ignored)
  3. Objects with circular references cannot be resolved

It is also the fastest built-in function to handle deep copies. Of course, if your data contains all three of these, you can use lodash’s deep-copy functions.

2.2.2 Native implementation of deep copy

const deepCopy = (sourceObj) = > {
  if(typeofsourceObj ! = ='object') return;
  let newObj = sourceObj instanceof Array ? [] : {};
  
  for(let key in sourceObj){
    if(sourceObj.hasOwnProperty(key)) {
     // Copy only the attributes of the element itself, not those on the stereotype chain
      newObj[key] = (typeof sourceObj[key] === 'object'? deepCopy(sourceObj[key]) : sourceObj[key]); }}return newObj;
}

let obj = { a:1.arr: [2.3]};
let res = deepCopy(obj);
console.log(res.arr === obj.arr); // false, pointing to a different reference
console.log(res === obj); // false
Copy the code

But deep copy is different, it not only copies each attribute of the original object one by one out, and the object contained in each attribute of the original object is also recursively copied to the new object by deep copy method. There is no problem with the arR attribute of obj and shallowObj pointing to the same object.

2.3 Copy in an Array

2.3.1 Array. The prototype. The slice ()

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

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

2.3.2 Array. The prototype. The 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

2.3.3 all

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:

! [](https://user-gold-cdn.xitu.io/2019/2/22/169156d156f7c222? w=720&h=270&f=jpeg&s=15463)
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.