Basic type & reference type
There are two types of data types in ECMAScript:
- Basic types: undefined, null, Boolean, String, Number, Symbol
- Reference types: Object, Array, the Date, the Function, the RegExp, etc
Different types of storage:
- Base type: Base type values occupy a fixed size in memory and are stored in stack memory
- Reference type: The value of a reference type is an object and is stored in heap memory, while the stack memory stores the variable identifier of the object and the location of the object in heap memory
Different types of replication modes:
- Basic type: Copying a value of a basic type from one variable to a new variable creates a copy of the value and copies it to the new variable
let foo = 1;
let bar = foo;
console.log(foo === bar); // -> true
// Changing the value of foo does not affect the value of bar
let foo = 233;
console.log(foo); / / - > 233
console.log(bar); / / - > 1
Copy the code
- Reference type: Copying a value of a reference type from a variable to a new variable is actually copying a pointer so that both variables end up pointing to the same object
let foo = {
name: 'leeper'.age: 20
}
let bar = foo;
console.log(foo === bar); // -> true
// Changing the value of foo affects the value of bar
foo.age = 19;
console.log(foo); // -> {name: 'leeper', age: 19}
console.log(bar); // -> {name: 'leeper', age: 19}
Copy the code
Deep copy & shallow copy
- Shallow copy: Only references are copied, and operations on each other affect each other
- Deep copy: Reallocate memory in the heap. Different addresses, same values, do not affect each other
In general, the main difference between deep and shallow copying is whether references are copied or instances are copied
The implementation of deep and shallow copy
Take a look at whether some of the replication methods provided in native JavaScript are deep copy or shallow copy, and get your hands dirty with deep copy.
Shallow copy
- Array.prototype.slice()
let a = [1.2.3.4];
let b = a.slice();
console.log(a === b); // -> false
a[0] = 5;
console.log(a); // -> [5, 2, 3, 4]
console.log(b); // -> [1, 2, 3, 4]
Copy the code
- Array.prototype.concat()
let a = [1.2.3.4];
let b = a.concat();
console.log(a === b); // -> false
a[0] = 5;
console.log(a); // -> [5, 2, 3, 4]
console.log(b); // -> [1, 2, 3, 4]
Copy the code
Array’s slice(),concat() looks like they are deep copies.
let a = [[1.2].3.4];
let b = a.slice();
console.log(a === b); // -> false
a[0] [0] = 0;
console.log(a); // -> [[0, 2], 3, 4]
console.log(b); // -> [[0, 2], 3, 4]
Copy the code
Similarly, concat() is validated:
let a = [[1.2].3.4];
let b = a.concat();
console.log(a === b); // -> false
a[0] [0] = 0;
console.log(a); // -> [[0, 2], 3, 4]
console.log(b); // -> [[0, 2], 3, 4]
Copy the code
In summary, Array’s slice and concat methods are not true deep copies. Array’s layer 1 elements are deep copies, while Array’s layer 2 slice and concat methods copy references. Therefore, Array’s slice and concat methods are shallow copies.
Deep copy
- JSON. The parse () and JSON. Stringify ()
- Json.stringify () : Serializes a JS object to a JSON string
- Json.parse () : deserialize the JSON string to a JS object
let obj = {
name: 'leeper'.age: 20.friend: {
name: 'lee'.age: 19}};let copyObj = JSON.parse(JSON.stringify(obj));
obj.name = 'Sandman';
obj.friend.name = 'Jerry';
console.log(obj);
// -> {name: "Sandman", age: 20, friend: {age: 19,name: 'Jerry'}}
console.log(copyObj);
// -> {name: "leeper", age: 20, friend: {age: 19,name: 'lee'}}
Copy the code
In summary, json.parse () and json.stringify () are full deep copies.
- Use recursion to achieve a deep copy of an object or array. Recursive idea: Iterate over the values of all reference types in the attribute until they are of the basic type.
function deepCopy(obj) {
if(! obj &&typeofobj ! = ='object') {
throw new Error('error arguments');
}
// const targetObj = obj.constructor === Array ? [] : {};
const targetObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
// Copy only the object's own properties
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === 'object') {
targetObj[key] = deepCopy(obj[key]);
} else{ targetObj[key] = obj[key]; }}}return targetObj;
}
Copy the code