Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
Shallow copy and deep copy is a popular interview question. Today we will summarize what shallow copy methods are available, as well as their advantages and disadvantages
First, what is a shallow copy
Create a new object of your own to accept the object values you want to copy or reference again. If the object property is a primitive data type, the value of the primitive type is copied to the new object. But if the property is a reference data type, the copy is the address in memory, and if one object changes the address in memory, the other object must be affected.
Object.assign
Object.assign is a method of Object. This method can be used to merge JS objects. The first argument to this method is the target object to copy, followed by the source object (or multiple sources) to copy.
const obj = {};
const source = {
name: 'nordon'.info: {
age: 18}};Object.assign(obj, source);
console.log(obj); // {name: 'nordon', info: {... }}
Copy the code
This is very convenient to complete the money copy, then you can modify the data
source.info.age = 20;
console.log(obj);
console.log(source);
Copy the code
After the modification, the age of both obj and source is 20, satisfying the shallow copy definition
Note:
- It does not copy the object’s inherited properties;
- It does not copy the object’s non-enumerable properties;
- Properties of type Symbol can be copied.
const obj = {};
const source = {
name: 'nordon'.symbol: Symbol()
};
Object.defineProperty(source, 'innumerable', {value:'innumerable'.enumerable:false
});
Object.assign(obj, source);
console.log(obj); // {name: 'nordon', symbol: Symbol()}
Copy the code
Common inherited attributes such as toString are not shallow copied by Object.assign
Extended operator
Shallow copies can also be made using extended operators
const source = {
name: 'nordon'.info: {
age: 18}};constobj = {... source};Object.assign(obj, source);
source.info.age = 20;
console.log(obj);
console.log(source);
Copy the code
The above code is the same as using object. assign, with the same precautions. They can be converted to each other
Array.prototype.concat
When concatenating an array with a reference type, you need to modify the attributes of the elements in the original array, because this will affect the concatenated array after copying
const arr = [1.2, {name: 'nordon'}];
const newArr = arr.concat();
newArr[2].name = 'wy';
console.log(arr);
console.log(newArr);
Copy the code
Arr and newArr index 2 are changed from **{name: ‘nordon’} to {name: ‘wy’}**
Array.prototype.slice
The slice method of arrays is actually a shallow copy with fewer scenarios, like cancat
const arr = [1.2, {name: 'nordon'}];
const newArr = arr.slice();
newArr[2].name = 'wy';
Copy the code
Use third-party libraries & manual implementation
There are several libraries of tools that can be used to implement shallow copies. Lodash, for example, provides the Clone method for shallow copies
Finally, let’s implement a shallow copy function ourselves
According to the above shallow copy definition, it can be clearly known that the core point of shallow copy is:
- Direct copy of data for underlying data types
- For reference type data, copy only the properties of the layer 1 object, creating a new address to store it (important difference between deep copy and shallow copy)
Now go straight to the code:
const clone = (target) = > {
// If it is a reference type
if (typeof target === "object"&& target ! = =null) {
// Determine whether it is data or object, and initialize a data for it
const cloneTarget = Array.isArray(target) ? [] : {};
// for in can iterate over a number of objects
for (let prop in target) {
if(target.hasOwnProperty(prop)) { cloneTarget[prop] = target[prop]; }}return cloneTarget;
} else {
// Base type returns directly
returntarget; }};Copy the code