Replication of JavaScript Arrays and Objects

  • 2021-08-05 08:26:04
  • OfStack

1. Data types

In a narrow sense, JS divides all data into two types: basic type and reference type, in which basic types include Undefined, Null, Boolean, Number and String, reference type is Object, and commonly used Array, Date, RegExp and Function all belong to Object type.

One of the differences between basic data and referenced data is that when copying variables, basic data copies an independent new copy, while referenced data copies a reference to the original variable. Here's an example:


//  Replication of primitive type data 
var a = 10;
var b = a; // b = 10
a = 20; // a = 20, b = 10
//  Replication of reference type data 
var m = [1, 2];
var n = m;
m[0] = 10;
console.log(n[0]); // 10

If I want to copy the value of the reference type itself instead of the reference, I obviously can't do it in the above way.

2. Shallow copy of arrays

Shallow copy means that when an object (array) is copied, the value of the referenced field is not copied, but the reference of the corresponding field is copied. Such as:


var src = [
 'alpha',
 ['bravo', 'chalie']
];
var dest = [];
for (var i = 0; i < src.length; i++) {
 dest[i] = src[i];
}
// At this point, if you change src Reference fields in the, dest The corresponding fields in will also be changed 
src[1].push('delta');
console.log(dest[1]); // ['bravo', 'chalie', 'delta']

Shallow copy 1 is generally used for 1-dimensional arrays, that is, there is no reference type in the array. Commonly used shallow replication methods are:

concat method


 var src = ['alpha', 'bravo'],
  dest = [];
 dest = dest.concat(src);

The concat method is more commonly used in combinations, such as:


 var a = ['alpha', 'bravo'],
  b = ['chalie', 'delta'],
  combine;
 combine = a.concat(b);

In particular, when concat is used for combination of arrays, it copies all the elements in two (or more) arrays to a new object, which is expensive for large arrays. A better way is to copy the elements of the last 1 array into the first 1 array:


 var src = ['alpha', 'bravo'],
  dest = ['chalie', 'delta'];
 Array.prototype.push.apply(src, dest);

slice method

The slice method returns a selected element from an existing array and returns a new array.


 var src = ['alpha', 'bravo'],
 var dest = src.slice(0);

3. Shallow copy of objects

Shallow replication of objects can be achieved using for-in traversals, and the more convenient Object. assign () method is provided in es6.


 var src = {name: 'fox', age: 20},
  dest = null;
 dest = Object.assign({}, src);

You can also use methods such as $. extend in jQuery, _. extend in underscore, etc.

4. Deep replication

The application scenarios of shallow replication are limited. In more cases, we hope to copy a complete copy of the object, which requires typeof or instanof operators to judge the types of each field. If a field is of basic type, it can be copied directly. If a field is of reference type, you need to make the above judgment for all the fields of that field, which makes it easy for us to consider using recursion to achieve this function.


function deep_copy(src, dest) {
 for (var p in src) {
  if (Array.isArray(src[p]) || src[p] instanceof Object) {
   dest[p] = Array.isArray(src[p]) ? [] : {};
   arguments.callee(dest[p], src[p]);
  }else {
   dest[p] = src[p];
  }
 }
}

In the above code, because arrays are special objects, they can be traversed using for-in.

Alternatively, you can use the json solution:


 function deep_copy_in_json(src) {
  return JSON.parse(JSON.stringify(src));
 }

Although this is relatively simple, many properties of the original object will be lost after operation, such as the construtor property and some methods in the object prototype.


Related articles: