copy
Talking about copy, in our actual development applications, for basic types, when the variable is assigned, it will automatically open up a new variable storage space, and for complex data types (objects), assignment operations need to think more;
Object copy mode
Object copy is divided into deep copy and shallow copy. The deep copy and shallow copy are mainly the object types contained in the object. As shown below, the distinction between obJ copies is mainly in offer;
var obj = {
name:'mfy'.age:18.offer: {company:'~'.jobs:'sercert'}}Copy the code
Shallow copy
Shallow copy solves the problem of references in objects; A shallow copy is a bitwise copy of an object. It creates a new object with an exact copy of the original object’s property values.
- If the attribute is of the base type, copy the value of the base type;
- If the attribute is a memory address (reference type), the memory address is copied
So if one object changes the address, it affects the other object. That is, the default copy constructor only copies the object shallowly (one member at a time), that is, only the object space is copied, not the resource.
Var a = {age:22, name:'mfy', data:{bane:'33', defa:'333 ',}}Copy the code
1.Object.assign()
The object.assgin () method can copy any number of the original Object’s own enumerable properties to the target Object and then return the target Object. But Object.assgin() makes a shallow copy, copying references to the attributes of the Object, not the Object itself.
var a ={
age:22.data: {name:'3333',}}var b = Object.assign({},a)
b.data.name =3;
b.age =333
console.log(b)
console.log(a)
Copy the code
When we modify the value of an internal property of an Object created by object.assgin (), the basic type of the Object is the newly created spatial storage, while the complex type, the Object type, is still a direct reference relationship, and modifying B affects A
2.Object.create(obj)
The first thing to be clear about is the use of the object.create () method
The ginseng
- When there is only one argument
var obj = Object.create({a:3})
console.log(obj)
var obj1 = Object.create(null)
console.log(obj1)
Copy the code
- When you pass two arguments
var obj2 = Object.create({a:3}, {foo: {
writable: true.configurable: true.value: 'hello'}})Copy the code
By referring to the location of the type when we pass a parameter, the __proto__ property is created much like a new Object
To copy
var a = {
age: 22.data: {
name: '3333',}}var c = Object.create(a)
c.age = Awesome!
c.data.name = 444
a.age = '18'
console.log('a', a)
console.log('c', c)
Copy the code
We can see that the reference to the object used by __proto__ in the variable c is the same as the reference to the object a
- Change the data.name property of variable C. Variable A has changed
- Modify the age property of variable A, variable C
__proto__
The age property of the
3. Expand operators
New methods in ES6;
var o = { age: 333.data: { name: 3232}}vard = { ... o } d.data.name ='d change name '
console.log('o',o)
console.log('d',d)
Copy the code
Array.prototype.concat()
Is an assignment to an object in an array;
var arr =[12.2323, {name:2}]
var arr2=arr.concat();
arr2[2].name =44
console.log(arr)
console.log(arr2)
Copy the code
Array.prototype.concat is a shallow copy of an Array in which an object has a reference relationship
5.Array.prototype.slice()
The implementation principle is the same as above, are copied basic properties, object references are still together, just copy an array, do not need the original array of data, can be treated as a special object;
Deep copy
Deep copy creates an identical object. The new object does not share memory with the original object, and changes to the new object will not change to the original object. When a is assigned to a by b, a new address reference is generated instead of the same address. So that a/ B can change each other without affecting each other;
1.JSON.parse(JSON.string(obj))
Json.parse (json.string (obj)) is one of the methods I often use in my work, and is of course context-sensitive;
var obj = {
offer: {
money: 13133.company: "A generation of gods"
},
name: 'mfy'
}
var obj2 = JSON.parse(JSON.stringify(obj));
obj2.offer.money = 'Change to custom money'
console.log('obj',obj)
console.log('obj2',obj2)
Copy the code
😢 shortcomings
Json.parse (json.string (obj)) provides a great deal of convenience, but there are drawbacks.
Unable to serialize functions ❗️
There are no functions contained in obj1 in obj2
var obj = {
fun:function(){console.log("I'm a function")},
name: 'mfy'
}
var obj2 = JSON.parse(JSON.stringify(obj));
console.log('obj',obj)
console.log('obj2',obj2)
Copy the code
😂 is ignored as undefined + and symbol is ignored
var a = Symbol('hh'.33);
var obj = {
name: 'mfy'.age:undefined,
a,
}
var obj2 = JSON.parse(JSON.stringify(obj));
console.log('obj',obj)
console.log('obj2',obj2)
Copy the code
2. Deep copy is implemented recursively
// No refinement
function deepMerge(obj) {
// Type verification is omitted
var target = {};
for (var key in obj) {
let itemObj = obj[key];
if (typeof itemObj == 'object') {
target[key] = deepMerge(itemObj)
} else {
target[key] = obj[key]
}
}
return target;
}
var obj3 = {age:18.name:'mfy'.offer: {company:'XXX'.jobs:333}}
var obj4 = deepMerge(obj3);
obj4.offer.company="big company"
console.log('obj4',obj4)
console.log('obj3',obj3)
Copy the code
Obj4 is deeply copied and the internal object type is changed again, which does not affect obj3. In this case, the storage mode and storage space of the two variables are unrelated
3. Use the loDash library
The loDash library also provides a method, deep copy, which is basically the same principle as 2
var _ = require('lodash');
var obj1 = {
a: 1.b: { f: { g: 1}},c: [1.2.3]};var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
Copy the code
conclusion
operation | The first level base data type changes | The second layer is reference type changes |
---|---|---|
The assignment | The raw data will change | The raw data will change |
Shallow copy | The original data will not change | The raw data will change |
Deep copy | The original data will not change | The original data will not change |
Reference documentation
The article was summarized a long time ago, the relevant reference materials were not marked at that time, so I can not find the link, hope to understand; 😂