An in depth analysis of JS's array traversal method of recommendation

  • 2021-06-28 11:01:29
  • OfStack

Friends who have used Underscore know that it has a very good API callable ability for traversing arrays (collections),.each() is one of them.Here is a simple example:


var arr = [1, 2, 3, 4, 5];
_.each(arr, function(el) {
console.log(el);
}); 

The code above will output 1, 2, 3, 4, 5 in turn. Is it interesting to walk through an array without writing your own for loop?The each() method is very useful for traversing arrays, but its internal implementation is not difficult at all.Let's see how.each().Before that, let's take a look at.API of each()..each() is typically called as follows:

_.each(arr, fn, context);

It receives three parameters,

The first is an array that needs to be traversed (objects are also possible, so let's talk about it later).

The second is its callback function, which passes in three parameters, function (el, i, arr), the current element, the current index, and the original array, respectively;

The third is the context to which the callback function needs to be bound, which specifies the this value of the callback function fn.

Okay, the needs are very clear. Start working!

Let's start with the simplest.each(), which cannot modify the context this, receives two parameters, coded as follows:


var _ = {}; //  Suppose this is underscore Ha 
// 1 The simplest _.each Implementation of the method 
_.each = function(arr, fn) {
 * for(var i = 0; i < arr.length; i++) {
 * fn(arr[i], i, arr);
 * }
 * return arr; //  Return the original array 
} 

What about?Is it easy?Just use an for loop and call the callback function continuously. In a few lines of code, it's done. I believe no one can understand it!Let's test 1 to see if it works:


var arr = [1, 2, 3, 4, 5];
_.each(arr, function(el, i, arr) {
 * console.log(el);
}); 

Open in the browser and the console will see the correct output.

So simple code 1 doesn't mean anything. Next, let's take a somewhat challenging example.For example, the array arr has an sum attribute. We need to sum all the elements of the array and store them in sum as follows:


var arr = [1, 2, 3, 4, 5];
arr.sum = 0; // sum Attributes are used to store the sum of array elements 
_.each(arr, function(el, i, arr) {
 * this.sum += el;
}); 

At this point, this is used in the callback function. If not bound, this defaults to window, which is not what we want. We want it to be bound to the array arr.call or apply can do this in the following code:


var _ = {}; //  Suppose this is underscore Ha 
// bind , receives two parameters fn and context
//  hold fn Bind to context Above 
var bind = function(fn, context) {
 * context = context || null;
 * return function(el, i, arr) {
 * fn.call(context, el, i, arr);
 * }
}
// _.each
_.each = function(arr, fn, context) {
 * //  call bind Method, put fn Bind to context Above 
 * fn = bind(fn, context);
 * for(var i = 0; i < arr.length; i++) {
 * fn(arr[i], i, arr);
 * }
 * return arr;
}
//  Test cases: 
var arr = [1, 2, 3, 4, 5];
arr.sum = 0; // sum Attributes are used to store the sum of array elements 
_.each(arr, function(el, i, arr) {
 * this.sum += el;
}, arr);
console.log(arr.sum); // 15 

Okay, this.The each () is powerful enough to properly traverse the array and optionally specify an this value to change the context of the callback function.However, as we mentioned earlier, Underscore's.each() can also traverse objects, and this implementation is not difficult, as long as you decide whether the first parameter passed in under 1 is an object or an array, if it is an array, as we did with 1, or if it is an object, use the for... in loop of the object to traverse.Interested ones can try it on their own, or look at the underscore source code.

Note: Since the ES5 standard, native arrays already have traversal methods such as Array.prototype.forEach, Array.prototype.Map, and native arrays can be used in projects.


Related articles: