js data type and deep and shallow copy

Posted by quercus on Sun, 23 Jan 2022 04:52:55 +0100

Js data type

Basic data types (value types): Number, String, Boolean, Undefined, Null, Symbol (unique value added in es6) and BigInt (added in es10);

Reference data type: Object. Contains Object, Array, function, Date, RegExp.

Deep copy

Only when the copy refers to the data type, the copy can be divided into shallow copy and deep copy

1. Shallow copy: directly assign the reference of the original object or the original array to the new object, the new array, and the new object / array is only a reference of the original object
2. Deep copy: create a new object and array, and copy the "value" (all elements of the array) of each attribute of the original object, which is "value" instead of "reference"

Why use deep copy?

When we change a new array (object), we do not change the original array (object)

Shallow copy (copy only the first level array elements)

array

Shallow copy is the creation of a new object that has an exact copy of the first level attributes of the original object. That is, if the attribute of the original object is basic type data, the copied value is the value of basic data type; If the property of the original object is a reference type, the memory address is copied. When the reference type attribute of the original object changes, the corresponding attribute value of the copied object will also change. It should be emphasized here that there is a difference between shallow copy and assignment. When assigning, it points to the same object as the original data, while shallow copy points to different objects.

1. Direct traversal

var arr = [1, 2, 3, 4];
function copy (arr) {
   let newArray = []
   for(let item of arr) {
      newArray.push(item);
   }
   return  newArray;
}
var copyArray = copy(arr);
copyArray[0] = 100;
console.log(arr); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]

2. slice() array method

When slice()Without any parameters, a new array with the same length as the original array is returned by default
var array = [1, 2, 3, 4];
var copyArray = array.slice();
copyArray[0] = 100;
console.log(array); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]

3. concat() array method

Because we call concat I didn't bring any parameters with me, so var copyArray = array.concat();Actually equivalent to var copyArray = array.concat([]);
That is, the returned array and an empty array are combined and returned
var array = [1, 2, 3, 4];
var copyArray = array.concat();
copyArray[0] = 100;
console.log(array); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]

object

1. Direct traversal

let obj = {code:200,list:[1,2,3,4]}
let newObj = {}
for(let i in obj) {
    newObj[i] = obj[i]
}
console.log(obj);
console.log(newObj);

2 .ES6 object assign

var obj = {
  name: 'Zhang San',
  job: 'student'
}
var copyObj = Object.assign({}, obj);
copyObj.name = 'Li Si';
console.log(obj);   	// {name: "Zhang San", job: "student"}
console.log(copyObj);  	// {name: "Li Si", job: "student"}

3. ES6 extension operator

let obj = {code:200,list:[1,2,3,4]}
let newObj = {...obj}
console.log(newObj);

Deep copy

Shallow copy is an exact copy of the first level attributes of the original object, while deep copy is a recursive exact copy of all levels of attributes of the original object.
1. First convert to string, and then convert to (array / object) JSON parse(JSON.stringify(XXXX))

let obj = {code:200,list:[1,2,3,4]}
let newObj = JSON.parse(JSON.stringify(obj))
newObj.list[1] = 1
console.log(obj);
console.log(newObj);

2. Handwritten deep copy

let obj = {code:200,list:[1,2,3,4]}
function deepClone(obj={}) {
    // First, judge whether it is a basic data type or a reference data type
    if(typeof obj != 'object' || obj == null) {
        return obj
    }
    // Second, distinguish between arrays and objects
    let result
    if(obj instanceof Array) {
        result = []
    } else {
        result = {}
    }
    // Finally, traverse
    for(let key in obj) {
        // If it is an attribute on the prototype, it will exist during initialization, so make sure that the key is not an attribute on the prototype
        // hasOwnProperty() determines whether it is its own property, which is not on the prototype
        if(obj.hasOwnProperty(key)) {   
            result[key] = deepClone(obj[key])   // recursion
        }
    }
    // Return results
    return result
}
let newObj = deepClone(obj)
newObj.list[1] = 1
console.log(obj);
console.log(newObj);

Topics: Javascript Front-end Vue.js