Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
In my work, my colleagues often ask me to help them check why the value of this data has changed even though I haven’t changed it. The reason for this problem is simply that the data is a reference type.
What are reference types
There are two types of data in JavaScript, basic type and reference type. Base type data is stored in stack memory, while reference type data is stored in heap memory.
When we assign a reference type Object to the variable obj1, the variable obj1 is stored in stack memory, and the data Object is stored in heap memory. When we access the variable obj1, the variable in stack memory will reference (access) the data Object in heap memory, so we call the data Object as reference type data.
If we assign the variable obj1 to the variable obj2, the variable obj2 will be added to stack memory. When we access the variable obj2, the variable obj2 in stack memory will also access the data Object in heap memory.
If you add the name attribute to obj2, you will change the Object in the heap. If you access obj1, you will find an extra name.
In real business, if you accidentally assign a value to a variable of a reference type to another variable and change that variable, you will have the phenomenon described at the beginning of this article — who moved my data?
Native reference types
There are several native reference types in JavaScript: Object, Array, RegExp, Date, Function, special primitive wrapper types (String, Number, Boolean), and single built-in objects (Global, Math). The most commonly used are only objects and arrays.
How do I avoid data being unaccountably changed
To avoid unexplained changes to data, simply process the data before assigning it to a variable and return a new data before assigning it. The purpose of processing is to return a new data, and there are several methods:
-
cloning
Cloning an object or array returns a new data.
-
JSON. Stringify () and JSON. The parse ()
Parse () returns a new object or array when it is parsed using json.stringify ().
-
slice
Const arr = [1, 2]; const arr1 = arr.slice();Copy the code
The above arr1 is a new array and changes have no effect on ARR.
-
map
Const arr = [1, 2]; const arr1 = arr.map((item) =>{ return item; })Copy the code
The above arr1 is a new array and changes have no effect on ARR.
-
filter
Const arr = [1, 2]; const arr1 = arr.map((item) =>{ return true; })Copy the code
The above arr1 is a new array and changes have no effect on ARR.
-
concat
Const arr = [1, 2]; const arr1 = arr.concat()Copy the code
The above arr1 is a new array and changes have no effect on ARR.
-
Object.assign
const obj = { a:1 }; const obj1 = Object.assign(obj); Copy the code
Obj1 above is a new object and changes have no effect on OBj.
-
ES6 extension operator
Const arr = [1, 2]; const arr1 = [...arr]Copy the code
The above arr1 is a new array and changes have no effect on ARR.
const obj = { a:1 }; const obj1 = {... obj};Copy the code
Obj1 above is a new object and changes have no effect on OBj.