1, Data type storage
As mentioned in the previous article, there are two major data types in JavaScript:
- Basic type
- reference type
The basic type data is saved in stack memory
The reference type data is stored in the heap memory. The variable of the reference data type is a reference to the actual object in the heap memory, which is stored in the stack
2, Shallow copy
Shallow copy refers to the creation of new data, which has an accurate copy of the attribute value of the original data.
If the attribute is a basic type, the value of the basic type is copied.
If the attribute is a reference type, the memory address is copied.
That is, the shallow copy is the copy layer, and the deep reference type is the shared memory address.
Achieve a simple shallow copy:
function shallowClone(obj) { const newObj = {}; for(let prop in obj) { if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }
In js, the phenomena of shallow copy include:
- Object.assign
- Array.prototype.slice(), Array.protortype.concat()
- Replication using extension operators
Object.assign
Object.assign: copy the values of all enumerable attributes from one or more data source objects to the target object, and return the target object at the same time.
Object.assign(target,...sources)
Where target is the target object, source is the source object, which can be multiple, and the modification returns the target object target.
1. If the attribute in the target object has the same attribute key, the attribute will be overwritten by the attribute in the source object;
2. The dependency of the source object will similarly override the previous properties.
// saucxs // First step let a = { name: "wywy", age: 21 } let b = { name: "xxx", book: { title: "You Don't Know JS", price: "45" } } let c = Object.assign(a, b); console.log(c); // { // name: "xxx", // age: 21, // book: {title: "You Don't Know JS", price: "45"} // } console.log(a === c); // true // Step two b.name = "change"; b.book.price = "55"; console.log(b); // { // name: "change", // book: {title: "You Don't Know JS", price: "55"} // } // Step 3 console.log(a); // { // name: "saucxs", // age: 18, // Book: {Title: "you don't know JS", price: "55"} price has changed // }
analysis:
Step 1:
Use object Assign (a, b). Copy the value of source object B to target object A. here, define the return value as c. It can be seen that B will replace the value with the same key in A. that is, if the attribute in target object a has the same key, the attribute will be overwritten by the attribute in source object B. The returned object c is the target object a.
Step 2: Step 2: modify the basic type value (name) and reference type value (book) of the source object b.
Step 3: after shallow copy, the basic type value of object a does not change, but the reference type value changes because object Assign () copies the attribute value. The attribute value added to the source object is a reference to the object, and only the reference address is copied.
slice()
slice() is used to create a new array containing one or more elements in the original array, which will not affect the original array
const fxArr = ["One","Two","Three"] const fxArrs = fxArr.slice(0) fxArrs[1] = "love"; console.log(fxArr) //["One","love","Three"] console.log(fxArrs) //["One","Two","Three"]
concat()
First, a copy of the current array will be created, then its parameters will be added to the end of the copy, and finally the newly constructed array will be returned without affecting the original array
const fxArr = ["One", "Two", "Three"] const fxArrs = fxArr.concat() fxArrs[1] = "love"; console.log(fxArr) // ["One", "Two", "Three"] console.log(fxArrs) // ["One", "love", "Three"]
Extension operator
const fxArr = ["One", "Two", "Three"] const fxArrs = [...fxArr] fxArrs[1] = "love"; console.log(fxArr) // ["One", "Two", "Three"] console.log(fxArrs) // ["One", "love", "Three"]
3, Deep copy
Deep copy opens up a new stack. The completion of two objects is the same, but corresponding to two different addresses. Modifying the properties of one object will not change the properties of the other object.
Common deep copy methods include:
- _.cloneDeep()
- jQuery.extend()
- JSON.stringify()
- Handwriting loop recursion
_.cloneDeep()
const _ = require('lodash'); const obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] }; const obj2 = _.cloneDeep(obj1); console.log(obj1.b.f === obj2.b.f);// false
JQuery.extend()
const $ = require('jquery'); const obj1 = { a:1, b:{f:{g:1}}, c:[1,2,3] } const obj2 = $.extend(true,{},obj1); console.log(obj1.b.f === obj2.b.f); //false
JSON.stringify()
const obj2 = JSON.parse(JSON.stringify(obj1));
However, there are disadvantages in this method, which ignores undefined, symbol, and functions
const obj = { name: 'A', name1: undefined, name3: function() {}, name4: Symbol('A') } const obj2 = JSON.parse(JSON.stringify(obj)); console.log(obj2); // {name: "A"}
Circular recursion
function deepClone(obj, hash = new WeakMap()) { if (obj === null) return obj; // If it is null or undefined, I will not copy if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj); // It may be an object or ordinary value. If it is a function, it does not need deep copy if (typeof obj !== "object") return obj; // If it is an object, you need to make a deep copy if (hash.get(obj)) return hash.get(obj); let cloneObj = new obj.constructor(); // What is found is the constructor on the prototype of the class, and the constructor on the prototype points to the current class itself hash.set(obj, cloneObj); for (let key in obj) { if (obj.hasOwnProperty(key)) { // Implement a recursive copy cloneObj[key] = deepClone(obj[key], hash); } } return cloneObj; }
4, Distinction
Illustration:
It can be seen from the above figure that both shallow copy and deep copy create a new object, but the behavior is different when copying object attributes.
Shallow copy only copies the pointer to an object, not the object itself. The old and new objects still share the same block of memory. Modifying the object properties will affect the original object.
However, deep copy will create another identical object. The new object does not share memory with the original object, and modifying the new object will not change to the original object.
5, Summary
When the copy type is reference type:
Shallow copy copies one layer. When the attribute is object, shallow copy copies. The two objects point to the same address
Deep copy is a recursive deep copy. When the attribute is an object, deep copy is a new stack, and the two objects point to different addresses.