Added in ES6 extended operator can operate on arrays and objects. Sometimes encounter copy arrays and objects, might use the extended operator. Then this extension operator in the end is a deep copy or a shallow copy of it?
A., Extended operator copies
The first is the following code.
let a = [1,2,3]; let b = [...a];
a == b // false
The result is false, it is very easy to know, after all, the assignment operator is different. The next will be just an array of change, what will happen;
let a = [1,2,3]; let b = [...a]; a[0] = 11; console.log(a); // [ 11, 2, 3 ] console.log(b); // [ 1, 2, 3 ]
Found b is not changed after a value is changed. So deep is the copy yet? Do not worry, the next element in the array is set to a reference type.
let a = [1,2,[1,2,3]]; let b = [...a]; a[2][1] = 11; console.log(a); // [ 1, 2, [ 1, 11, 3 ] ] console.log(b); // [ 1, 2, [ 1, 11, 3 ] ]
console.log(a[2] === b[2]); // true
The interesting result of this, if the reference values in the array type element is changed, then the values of a and b will change, and a reference type and b congruent, that address is the same. So why is this?
Two., Cause
This is only my first analysis of the current perception.
For extended operator array is only a shallow copy, only the data of the first reference type layer of the copy, and then deep-level if no copy is performed.
Further extension of the operator and the array is the same as the object.
let a = { name : "Jyy", msg : { age : 29 } } let b = {...a}; console.log(a == b); // false console.log(a.msg == b.msg); // true; a.msg = { age : "28" } console.log(a); // { name: 'Jyy', msg: { age: '28' } } console.log(b); // { name: 'Jyy', msg: { age: 29 } }
Third, the deep and shallow copy copy method
1. Method shallow copy
The above example has been seen in es6 extended operator merely a copy of a reference to the types of the first layer. In addition to extended operator es6 other methods
Object:
Use Object.assign ()
Object.assign () for the combined object, if the first parameter is {}, you may be on the back of copy object parameters
let a = { name : "Jyy", msg : { age : 29 } } let b = Object.assign({},a); console.log(a == b); // false console.log(a.msg == b.msg); // true; a.msg = { age : "28" } console.log(a); // { name: 'Jyy', msg: { age: '28' } } console.log(b); // { name: 'Jyy', msg: { age: 29 } }
Array:
Many methods shallow copy of the array
a. Using slice ()
slice may intercept part of the array elements, if the argument is null, the array can be shallow copy
let a = [1,2,[1,2,3]]; let b = a.slice(); console.log(a == b); // false a[2][1] = 11; a[0] = 11; console.log(a); // [ 11, 2, [ 1, 11, 3 ] ] console.log(b); // [ 1, 2, [ 1, 11, 3 ] ] console.log(a[2] == b[2]); // true
b. Using concat ()
concat array can be merged, if the argument is null, the array may be shallow copy
let a = [1,2,[1,2,3]]; let b = a.concat(); console.log(a == b); // false a[2][1] = 11; a[0] = 11; console.log(a); // [ 11, 2, [ 1, 11, 3 ] ] console.log(b); // [ 1, 2, [ 1, 11, 3 ] ] console.log(a[2] == b[2]); // true
c. Use Array.from ()
let a = [1,2,[1,2,3]]; let b = Array.from(a); console.log(a == b); // false a[2][1] = 11; a[0] = 11; console.log(a); // [ 11, 2, [ 1, 11, 3 ] ] console.log(b); // [ 1, 2, [ 1, 11, 3 ] ] console.log(a[2] == b[2]); // true
2. deep copy
For deep copy, method and object arrays are consistent
a. recursion method is to use layers of loop for copying, a specific code is not written
b.JSON.parse()
This method is typically string data transmission parameters for the call interface or the object is returned to the turn.
let a = { name : "JYY", age : "25", msg : { addr : "hebei" } } b = JSON.parse(JSON.stringify(a)); console.log(a == b); // false console.log(a.msg == b.msg); // false a.msg.addr = "chengde"; console.log(a); // { name: 'JYY', age: '25', msg: { addr: 'chengde' } } console.log(b); // { name: 'JYY', age: '25', msg: { addr: 'hebei' } }
The drawbacks of this method is that undefined
, function
, symbol
are ignored in the conversion process
let a = { name : "JYY", age : "25", msg : { addr : "hebei" }, speek : function(){ console.log(this.name); } } b = JSON.parse(JSON.stringify(a)); console.log(a); // { name: 'JYY', height: Symbol(jyy), age: undefined, msg: { addr: 'chengde' },speek: [Function: speek] } console.log(b); // { name: 'JYY', msg: { addr: 'hebei' } }
c. Use a third-party plug-ins
For example lodash deep copy
const _ = require("lodash"); let syb = Symbol('jyy'); let a = { name : "JYY", height: syb, age : undefined, msg : { addr : "hebei" }, speek : function(){ console.log(this.name); } } let b = _.cloneDeep(a); console.log(a == b); // false console.log(a.msg == b.msg); // false console.log(a); // { name: 'JYY', height: Symbol(jyy), age: undefined, msg: { addr: 'chengde' },speek: [Function: speek] } console.log(b); // { name: 'JYY', height: Symbol(jyy), age: undefined, msg: { addr: 'chengde' },speek: [Function: speek] }