Deep copy of JS objects in the development of the project is more commonly used, this article illustrates the common DEEP copy of JS objects. For use in development. Nonsense not to say, the first commonly used deep copy conclusion, the conclusion behind is correspondence analysis

The deep copy mode is commonly used

  • JSON.parse(JSON.stringify())
  • Object.assign
  • . Extended operator
  • Lodash function library

About copying variables (data types) in JS

As we know, basic data types and reference data types are commonly used in JS language

Basic data types

Classification of basic data types

  • string
  • number
  • boolean
  • null
  • undefined

Base data type replication

Since the values of the primitive data type are stored in the stack, they can be copied directly using an equal sign =, but the reference data type stack holds only a pointer address that points to the data in the heap. So the copying of reference data types is a little bit trickier.

Reference data type

Reference data type classification

  • object
  • An array of
  • function

Reference data type replication

As we know, data replication (copying) is essentially finding a separate block of memory to store the corresponding specific information, and this part of the information is separate from the original. For a copy of a reference data type, if you use the equal sign to assign a copy, you just give the pointer to the reference data type to the variable. Functions generally do not need to do copy, because the function is a first-class citizen in JS, where you need to use a direct call to the function, so when talking about deep copy or shallow copy of the word, generally refers to the object or data copy, object copy a little more

Deep copy of object

Shallow copy, just equal to sign = assignment, I don’t need to go into here

Scenario assumptions

Suppose there is a table on our project page, and each row in the table is the corresponding data. There is an edit button on the right side of the table. Click the edit button, and a pop-up box will appear. The logic is simple: click the edit button on a row, get the corresponding row’s data, and assign the corresponding row’s data to the form. The following two graphs show the difference between no deep copy and deep copy

Do not use deep copy renderings

Instead of using deep copy, assign rowData directly to the form. We find that when we modify the data in the form, the corresponding row in the table is also modified because we assign only the pointer reference address of the object. That’s obviously not what we want, so it doesn’t work that way in general.

Use deep copy renderings

We found that using deep copy, we changed the data in the form without changing the corresponding row in the original table, which is what we want.

The corresponding code

<template>
  <div id="app">

    <! -- Table section -->
    <el-table :data="tableData" border style="width: 100%">
      <el-table-column prop="name" label="Name" width="180"> </el-table-column>
      <el-table-column prop="age" label="Age" width="180"> </el-table-column>
      <el-table-column prop="home" label="Home"> </el-table-column>
      <el-table-column fixed="right" label="Operation" width="100">
        <template slot-scope="scope">
          <el-button type="primary" plain size="small" @click="editRow(scope.row)"
            >Edit < / el - button ></template>
      </el-table-column>
    </el-table>

    <! -- Popbox forms section -->
    <el-dialog
      title="Edit table"
      append-to-body
      :close-on-click-modal="false"
      :visible.sync="dialogVisible"
      width="30%"
    >
      <el-form ref="form" :model="form" label-width="80px">
        <el-form-item label="Name">
          <el-input v-model.trim="form.name"></el-input>
        </el-form-item>
        <el-form-item label="Age">
          <el-input v-model.trim="form.age"></el-input>
        </el-form-item>
        <el-form-item label="Home">
          <el-input v-model.trim="form.home"></el-input>
        </el-form-item>
      </el-form>
    </el-dialog>

  </div>
</template>

<script>
// Introduce the lodash library
import _ from 'lodash'
export default {
  components: {},
  data() {
    return {
      // Table data
      tableData: [{name: "Sun Wukong".age: "500".home: "Water Curtain Cave of Huaguo Mountain"}, {name: "Pig Eight Quit".age: "88".home: "Lao Zhuang Gao"],},dialogVisible: false.// Form data
      form: {
        name: "".age: "".home: "",}}; },methods: {
    editRow(rowData) {
      console.log("rowData".this.form);
      this.dialogVisible = true;

      // // No deep copy, direct assignment
      // this.form = rowData

      // // Deep copy method a JSON method
      // this.form = JSON.parse(JSON.stringify(rowData));

      // // Object. Assign method of deep copy mode 2
      // this.form = Object.assign({},rowData)

      // // Extended operator of deep copy mode three
      // let { ... newObj } = rowData
      // this.form = newObj

      // // Deep copy mode four lodash function library
      this.form = _.cloneDeep(rowData) // Calling lodash's cloneDeep method can also do deep copy,}}};</script>

<style lang="less" scoped>
#app {
  width: 100%;
  height: 100vh;
  box-sizing: border-box;
  padding: 50px;
}
/deep/ .el-dialog {
  margin-top: 30vh ! important;
}
</style>
Copy the code

Add a deep copy of the ~ array

For array copy, if the equal sign = is used directly to copy the array, it is only a shallow copy, the shallow copy is the address, so the source array changes, the copied array will also change

Common way

  • slice
  • concat
  • . expand
  • JSON.parse(JSON.stringify())
let arr = [Sun Wukong.'Pig Eight Quit'.'Sand Monk'."Tang's monk]

// Mode one slice
let newArr = arr.slice(0)

// Concat
let newArr = arr.concat()

// Method 3... Extended operator
let [ ...newArr ] = arr

4 / / way
let newArr = JSON.parse(JSON.stringify(arr))
Copy the code

You can also use loDash’s library of functional tools