This is the first article I participated in beginners’ introduction

concept

First, let’s mention data types in JavaScript. There are eight data types in JavaScript: String, Number, Boolean, Null, Undefined, Object, Symbol, and bigInt

Number supports a limited range of integers. BigInt automatically rounds off large integers, resulting in loss of precision. BigInt supports integers larger than Number, which is suitable for mathematical operations.

Except Object, which is a reference data type, the other seven are all basic data types. Replication between basic data types returns new data, which are all in independent stacks and can be copied at will without being affected.

Reference data types Object, like Array, Function, Date, RegExp… Are reference data types

Reference data type in heap memory, can directly access and modify, but due to the reference data types to occupy the space is large, performance problems on the stack, so keep a stack of heap pointer to point to the original address, when the interpreter for reference value, first retrieve the stack in the address, data captured by the address from the heap

The assignment of a reference data type copies an address pointer from the stack, so both variables point to the same object. Changing one variable will result in changing the other. Sometimes a new, independent copy of data needs to be made, and some method is needed to copy it.

Pointers to the same address:

let obj = {
  name:'Joe'.age:20,}let newObj = obj     // Assign the pointer to the reference directly
obj.name = 'bill'    // If you modify the property in obj, newObj will also change, because they are essentially the same

console.log(obj)     // {name: 'li ', age: 20}
console.log(newObj)  // {name: 'li ', age: 20}

Copy the code

Shallow copy

Shallow copy only copies one layer, and deeper object copy only copies references (addresses). There are several ways to implement this:

cycle

Shallow copy is achieved by looping through assignments

let obj = {
  name:'Joe'.age:20.skill: {
    name: 'javascript'}}let newObj = {}

for (let key in obj) {
  newObj[key] = obj[key];
}

obj.name = 'bill'
obj.skill = 'Node'

console.log(obj)    / / {name: "bill", the age: 20, skill: {name: 'Node'}}
console.log(newObj) / / {name: 'zhang' age: 20, skill: {name: 'Node'}}
Copy the code

Object.assign

For details about how to add ES6 objects, see

This method is used to assign the values of all enumerable properties from one or more source objects to the target object. It will return the target object.

Grammar:

Object.assign(target, ... sources)

parameter

Target Target object

Sources source object

return

The source object

example

let obj = {
  name:'Joe'.age:20.skill: {
    name: 'javascript'}}let newObj = Object.assign({}, obj)

obj.name = 'bill'    // Copy the value of the first layer
obj.skill = 'Node'  // Layer 2 copy references

// Skill is the same as the reference
console.log(obj)    / / {name: "bill", the age: 20, skill: {name: 'Node'}}
console.log(newObj) / / {name: 'zhang' age: 20, skill: {name: 'Node'}}
Copy the code

Extended operator (.)

Extended operators for ES6 new features see

let obj = {
  name:'Joe'.age:20.skill: {
    name: 'javascript'}}letnewObj = { ... obj} obj.name ='bill'  
obj.skill = 'Node' 

// Copy only the first layer
console.log(obj)    / / {name: "bill", the age: 20, skill: {name: 'Node'}}
console.log(newObj) / / {name: 'zhang' age: 20, skill: {name: 'Node'}}
Copy the code

defects

If there is a reference value in the copy object, the reference value points to the same address. Modifying one will affect the other.

However, if you only have one layer of objects to copy, shallow copies are also useful.

Deep copy

Deep copy can create a new memory space for all reference types encountered in the copy process to avoid the problem that child objects share the same memory.

JSON method

Deep copy is achieved by converting an object to a JSON string using the json.stringify () method and then going back to the object using json.parse ()

let obj = {
  name:'Joe'.age:20.skill: {
    name: 'javascript'}}let newObj = JSON.parse(JSON.stringify(obj))

obj.name = 'bill'  
obj.skill = 'Node' 

// Implement deep copy
console.log(obj)    / / {name: "bill", the age: 20, skill: {name: 'Node'}}
console.log(newObj) // {name: 'javascript', age: 20, skill: {name: 'javascript'}}
Copy the code

This looks good, but there is a drawback to this method: you cannot copy special objects such as RegExp and Date, and there are all sorts of problems that make copying impossible.

Function encapsulation

Wrapping a deep-copy function is a good way to do it. Through recursive implementation of multi-level copy, more applicability.

The main idea is shallow copy + recursion

  • Direct copy of basic data types
  • Reference data types for recursive copying
// Check whether it is a reference data type
function isObject(target) {
  const type = typeof target
  returntarget ! = =null && (type === 'object' || type === 'function')}/ / copy
function deepClone(target) {
  // Basic data types are returned directly
  if(! isObject(target))return target 
  
  // Determine whether an object is an array and return an empty variable of the corresponding type
  let cloneTarget = Array.isArray(target) ? [] : {}
  Object.keys(target).forEach(key= > {
    // Loop assignment, copy the next layer recursively
    cloneTarget[key] = deepClone(target[key]) 
  })
  return cloneTarget
}

/ / have a try
let obj = {
  name:'Joe'.age:20.skill: {
    name: 'javascript'}}let newObj = deepClone(obj)

obj.name = 'bill'  
obj.skill = 'Node' 

// Implement deep copy
console.log(obj)    / / {name: "bill", the age: 20, skill: {name: 'Node'}}
console.log(newObj) // {name: 'javascript', age: 20, skill: {name: 'javascript'}}
Copy the code

conclusion

  1. Basic data types can be copied at will.
  2. Reference data type For performance reasons, variables are stored in the heap corresponding Pointers, directly copied Pointers also.
  3. There are several ways to shallow copy, but only the first layer is copied, and subsequent copies are Pointers
  4. Deep copy withJSONMethod transformations can address most requirements, except for some special objects.
  5. The idea of encapsulating deep copy is as follows: Basic data types are returned directly, and complex data types are processed recursively to achieve layer upon layer copy.