In the daily brick moving process, often contact with data copy, idle, do a simple summary record.
Actually speaking of copy, we often divide it into deep copy & shallow copy, so what is the difference between the two?
What is deep copy and shallow copy
- Shallow copy:
Shallow copy copies only the properties of the object sequentially, not recursively, that is, only the first-level properties of the target object are assigned. For the data of the basic data type in the first layer of the target object, it is directly assigned, that is, “pass value”; For the first layer of the target object that refers to the data type, it is the heap memory address directly stored in the stack memory, that is, “address”. So when you operate on a source object or a target object, it can affect each other.
- Deep copy:
Deep copy differs from shallow copy in that it copies not only the first layer properties of the target object, but all properties of the target object recursively. It creates an identical object on top of the target object. The old and new objects do not share memory, so modifying one object does not affect the other. When the copy action is complete, the source object is no longer related to the copy object. Now that we know the difference and meaning of light copy, what are the ways to achieve light copy?
Deep copy implementation
- JSON.parse(JSON.stringify(obj)
const source = {
num: 1.str: 'string'.arr: ['array'].obj: { object:'object'}}const target = JSON.parse(JSON.stringify(source));
source.num=2;
source.obj.object='newStr'
console.log(target === source);
// false
console.log(target);
/ / {
// num: 1,
// str: 'string',
// arr: ['array'],
// obj: { object:'object' }
// }
Copy the code
Json.stringify () serializes a JS object to a JSON string, and json.parse () deserializes a JSON string to a JS object, which creates a new object when converted from a JSON string to a JS object. However, such hacking still has the following drawbacks:
- Undefined and Symbol are ignored
- Non-serializable function
- Invalid for objects referenced in the loop
Take the following example:
const symbol=Symbol(a)const fun = () = >{return 'i am a function'}
const source = {
symbol,
fun,
un: undefined
}
const target = JSON.parse(JSON.stringify(source));
console.log(target);
/ / {}
let obj = { a: 1.b: 3 }
obj.c = obj
JSON.stringify(obj)
// Uncaught TypeError: Converting circular structure to JSON
Copy the code
- A recursive copy
const deepClone = function (obj) {
if (typeofobj ! = ='object') {
return obj
}
const newObj = obj instanceof Array ? [] : {}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
}
}
return newObj
}
Copy the code
Shallow copy implementation
- Object.assign({},obj)
The object.assign () method is used to copy the values of all enumerable properties from one or more source objects to the target Object and return the target Object.
const source = {
num: 1.str: 'string'.arr: ['array'].obj: { object: 'object'}}const target = Object.assign({}, source);
source.num = 2;
source.obj.object = 'newStr'
console.log(target === source);
// false
console.log(target);
/ / {
// num: 1,
// str: 'string',
// arr: ['array'],
// obj: { object: 'newStr' }
// }
Copy the code
Object.assign({},obj) is a shallow copy of object.assign ({},obj). If an attribute value of the reference type is assigned, the reference pointer is copied instead of creating a new memory.
- Deconstruction assignment
ES6 provides a way to manipulate objects directly: destruct assignment. Copy objects by destructing and assigning them to the source object:
const source = {
num: 1.str: 'string'.arr: ['array'].obj: { object: 'object'}}consttarget = { ... source }; source.num =2;
source.obj.object = 'newStr'
console.log(target === source);
// false
console.log(target);
/ / {
// num: 1,
// str: 'string',
// arr: ['array'],
// obj: { object: 'newStr' }
// }
Copy the code
End, scatter flowers!