Knowledge base – Data types

In JS, our data types fall into the following two categories:

Basic types: number, string, Boolean, null, undifined, symbol

Reference types: Object,array,function

It is important to distinguish between these two types of data. The main difference is where they are stored in memory.

Heaps and stacks in JavaScript

First, let’s talk about why the storage location is different:

  • Basic types are also calledPrimitive data typeIs simple data stored directly on the stack, its main characteristic isSmall space.Fixed size.Frequently used
  • Reference types are objects stored in the heap, and their main characteristic isTake up space.Unfixed size, do not store it on the stack because the data is too large to affect performance. But reference types create space in the stack to hold a reference address to the object stored in the heap, so you can think of the reference address stored in the stack as a bunchThe keyObjects in the heap are regarded as a fanThe doorThe keys all match.

The difference between heap and stack:

  • The heap is larger than the stack, and the stack runs faster than the heap
  • Heap memory is unordered storage and can be retrieved directly by reference
  • The underlying data types are stable and relatively memory intensive
  • The reference data type size is dynamic and unlimited

The assignment

Basic datatype: The assignment of a variable to a basic datatype creates a new space on the stack to store the variable. The two variables are not affected by each other. When you modify one variable, the other variable does not change.

var a = 1;
var b = a;
a = 999
console.log(a)   // 999
console.log(b)   // 1
Copy the code

Illustration:

Reference type: Assigning a reference type is equivalent to assigning a variable the address of a reference to the same object. This can be a problem. Since both variables refer to the same object as references, modifying the attributes of the object affects each other. It’s all the properties of the object, regardless of the data type. Notice that.

var obj = {
    name: 'liming',
    son: {
        name: 'xiaoming',
        age: 19
    }
}
var objCopy = obj
objCopy.name = 'zhanghong'
objCopy.son.name = 'xiaohong'

console.log(obj)       // {
                                name: 'zhanghong',
                                son: {
                                    name: 'xiaohong',
                                    age: 19
                                }
                            }
                            
console.log(objCopy)   // {
                                name: 'zhanghong',
                                son: {
                                    name: 'xiaohong',
                                    age: 19
                                }
                            }
Copy the code

Illustration:

Conclusion: Here we can understand that the two people have the same door key, that is, objCopy got the key of OBJ’s door and made an identical one where the key was matched. At this point, both can open the door, and whatever is inside the door will affect each other no matter who moves it.

Shallow copy

Let’s talk about shallow and deep copies: we are copying for reference types, so keep in mind.

Let’s write a shallow copy by hand. See the following example:

var obj = { name: 'liming', son: { name: 'xiaoming', age: 19}} var objCopy = shallowCopy(obj) function shallowCopy(object){var newObj = {}; for(var prop in object ){ if(object.hasOwnProperty(prop)){ newObj[prop] = src[prop] } } return newObj } // The hasOwnProperty() method returns a Boolean, Objcopy. name = 'zhanghong' objcpy.son. name = 'xiaohong' console.log(obj) //{name: 'liming', son: { name: 'xiaohong', age: 19 } } console.log(objCopy) //{ name: 'zhanghong', son: { name: 'xiaohong', age: 19 } }Copy the code

Illustration:

As you may have noticed, basic type changes do not affect each other after a shallow copy, but reference type values do. Here’s why:

  • A shallow copy is an exact assignment of values to the original object. If it is a copy of the basic type, the value of the basic type is copied. Modifying the value of the basic type does not affect the original object.
  • If a shallow copy needs to copy the reference type, it copies the reference address of the value of the original object reference type. In this case, it is equivalent to the value of the reference type. Both objects hold the same key, and changing the value of the reference type will affect each other.

Summary: Shallow copy is only for the first layer of the object data, the basic type of data is a copy of the value, but the reference type is still a copy of the reference address, which will affect each other.

Shallow copy implementation method:

There are many shallow copy methods that we use in our daily development. Here are some of them:

  • Object.assign()

The object.assign () method copies the enumerable properties of any number of source objects to the target Object and returns the target Object.

var obj = { name: 'liming', son: { name: 'xiaoming', age: 19 } } var objCopy = Object.assign({},obj) objCopy.name = 'zhanghong' objCopy.son.name = 'xiaohong' console.log(obj) //{  name: 'liming', son: { name: 'xiaohong', age: 19 } } console.log(objCopy) //{ name: 'zhanghong', son: { name: 'xiaohong', age: 19 } }Copy the code
  • Array slice() method
        var arr = ['hello', 25, { sex:'man' }];
        let arr1 = arr.slice()
        arr1[2].sex='women'
        arr1[0]='world'
        console.log( arr )     // ['hello', 25, { sex:'women' }];
        console.log( arr1 )    // ['world', 25, { sex:'women' }];
Copy the code
  • Array concat() method
        var arr = ['hello', 25, { sex:'man' }];
        let arr1 = arr.concat()
        arr1[2].sex='women'
        arr1[0]='world'
        console.log( arr )     // ['hello', 25, { sex:'women' }];
        console.log( arr1 )    // ['world', 25, { sex:'women' }];
Copy the code
  • ES6 deconstructs assignment
let a = { age: 18, name: 'liming', address: { city: 'nanjing' } } let b = {... a}; b.age=80 b.address.city = 'beijing'; console.log(a) // { age: 18, name: 'liming', address: { city: 'beijing' } } console.log(b) // { age: 80, name: 'liming', address: { city: 'beijing' } }Copy the code

Deep copy

We must know that the deep copy is to reference the type of variable assignment, so that the two variables are completely independent of each other, to avoid development logic problems.

Implementing deep copy manually:

The manual implementation of deep copy uses recursion

Var obj = {var obj = { Name :"hello", count:{a:1, b:2}, fn:function(){}, List :[1,2,3,[22,33]]} function copy(obj){let newobj = null; // Determine if the data type is complex, if it is, call yourself, loop again, if not, assign the value directly, // Since null can't loop but the type is object, If (typeof(obj) == 'object' &&obj! Newobj = obj instanceof Array? Newobj = obj instanceof Array? [] : {}; // For each item in the loop obj, if there are complex data types in it, For (var I in obj){newobj[I] = copy(obj[I])}}else{newobj = obj} return newobj; // The function must return a value, Var objCopy = copy(obj) obj2.list[0] = 999 obj2.name = 'world' obj2.count. Name: "hello," the count: 2} {a: 1, b:, fn: function () {}, list: [1, 2, 3, 33] [22]} the console. The log (obj2) / / {name: "the world", Count: {2} a: 100, b:, fn: function () {}, list: [999, 2, 3, 33] [22]}Copy the code

Illustration:

Supplementary deep copy methods:

  • JSON. The parse () with JSON. Stringify ()
        var arr = ['hello', 25, { sex:'man' }];
        let arr1 = JSON.parse(JSON.stringify(arr))
        arr1[2].sex='women'
        arr1[0]='world'
        console.log( arr )     // ['hello', 25, { sex:'man' }];
        console.log( arr1 )    // ['world', 25, { sex:'women' }];
Copy the code

There are many disadvantages to this method of deep copy, to name a few common ones:

  1. The time object in obj will just be a string. Not a time object.
  2. If there are RegExp and Error objects in obj, the result will be empty objects.
  3. The function in obj, undefined gets lost.
  4. NaN, Infinity, and -infinity in obj become null
  • Implement deep copy with third-party deep copy libraries

This method is the most practical, relatively recommended use, low cost, basic error. A common third-party library is LoDash.

So that’s the end of the article. The summary is shown in the following table:

operation Whether to point to the same heap address Basic data types Reference data type
The assignment is changewillChange the original data changewillChange the original data
Shallow copy no changeDon'tChange the original data changewillChange the original data
Deep copy no changeDon'tChange the original data changeDon'tChange the original data

If there are any mistakes in this article, please correct them. Thanks for watching!