[Effective JavaScript notes] 50th: Iterative methods are better than loops

Source: Internet
Author: User
Tags terminates

"Lazy" programmers are good programmers. Copy and paste boilerplate code, one but the code is wrong, or the code function is modified, then the program at the time of modification, the programmer needs to find all the same functions of the code is changed everywhere. This makes it possible to reinvent the wheel and to see the solution at a higher level when others are looking at the code. Too easy to get into the details.

For loop

The For loop in JS can introduce different behaviors when it makes some minor changes. When programming, the judgment of boundary conditions often leads to some simple mistakes. Some minor changes to the for loop below cause changes in the boundary conditions.

for(var i=0;i<=n;i++){...}//包括最后的迭代for(var i=1;i< n;i++){...}//忽略第一次迭代for(var i=n;i>=0;i--){...}//包括第一次迭代for(var i=n-1;i > 0;i++){...}//忽略最后的迭代

Here is a setting for the termination condition. There can be many ways to make the termination condition error.
The closure of JS is a kind of iterative and abstract convenient and expressive technique for these patterns, which avoids duplication of code.

Array methods in ES5

The array method provided in ES5 contains many. Like what

Array.prototype.forEach

For example, the following loop of the array.

for(var i=0,n=players.length;i< n;i++){    players[i].score++;}

Using an iterative method of arrays, you can override the

players.forEach(function(p){    p.score++;});

The above code abstracts the loop in the way that the specific code to execute is passed through the function closure, and the operation and access of the array elements are accomplished. This eliminates the termination condition and any array indexes.

Array.prototype.map

Create a new array after you have done some operations on each element of the array.

Using loops
var trimmed=[];for(var i=0,n=input.length;i< n;i++){    trimmed.push(input[i].trim());}
Using the Foreach
var trimmed=[];input.forEach(function(s){    trimmed.push(s.trim());});
Using map
var trimmed=input.map(function(s){    return s.trim();});
Array.prototype.filter

Computes an array to create a new array that contains only some elements of the array
The filter method requires a predicate function that returns the true value if the element should exist in the new array, or False if the element should be rejected. For example, you can extract a list of a specific price range from the price list.

listings.filter(function(listing){    return listing.price>=min&&listing.price<=max;});

The Foreach,map,filter three methods above are the default methods for arrays in ES5. The following implements an iterative abstraction of its own.
Example: Extracts the first few elements of an array that satisfy the predicate function until the element that does not satisfy terminates, regardless of whether or not the element satisfies the condition.

function takeWhile(a,pred){   var res=[];   for(var i=0,n=a.length;i < n;i++){      if(!pred(a[i],i)){          break;      }      res[i]=a[i];   }     return res;}var prefix=takeWhile([1,2,3,4,26,18,9],function(n){    return n<10;});prefix;//[1, 2, 3, 4]

The Pred function above has two parameters, and the following callback we pass only one parameter. It doesn't matter if the second parameter is not processed.

Monkey Patch

Add the TakeWhile function to the array.prototype to make it a method.

Array.prototype.takeWhile=function(pred){    var res=[];    for(var i=0,n=this.length;i < n;i++){      if(!pred(this[i],i)){          break;      }      res[i]=this[i];    }      return res;};var prefix=[1,2,3,4,26,18,9].takeWhile(function(n){    return n<10;});prefix;//[1, 2, 3, 4]
Cyclic Control flow Operations

Only a little loop is better than an iteration, and loops can control flow operations such as break and continue.
For example, using the Foreach method to implement the TakeWhile function

function takeWhile(a,pred){    var res=[];    a.forEach(function(x,i){        if(!pred(x)){          //?        }        res[i]=x;    });    return res;}

How the above code terminates the execution of the loop.

Inner exception
function takeWhile(a,pred){    var res=[];    var earlyExit={};    try{        a.forEach(function(x,i){            if(!pred(x)){              throw earlyExit;            }            res[i]=x;        });    }catch(e){        if(e!==earlyExit){            throw e;        }    }    return res;}

This approach, the original simple processing has become more complex, not desirable.

Some,every

There is no easier way. Here's a look at the array of methods provided to terminate the loop prematurely. Some and every.

The Some method returns a Boolean value that indicates whether any element of its callback array returns a truth.

I understand:
All elements, for the judgment of the incoming function, one true is true. All false is false.
Equivalent to all elements executed after the function is taken or.

[1,10,100].some(function(x){return x>5;});//true[1,10,100].some(function(x){return x<0;});//false
The Every method returns a Boolean indicating whether its callback function returns a true value for all elements.

I understand:
All elements, for the judgment of the incoming function, have a false or false. It is true that all is true.
Equivalent to all element execution functions after fetching and.

[1,10,100].every(function(x){return x>5;});//false[1,10,100].every(function(x){return x>0;});//true

Both of these methods are short-circuit loops. The subsequent loop is no longer executed as long as the resulting result can determine the final result. That is, once the some produces a true value, it returns immediately. Every once a false value is generated, it is returned immediately.
Using their features, rewrite the TakeWhile function.

function takeWhile(a,pred){    var res=[];    a.every(function(x,i){        if(!pred(x)){           return false;//break        }        res[i]=x;        return true;    });    return res;}
Tips
    • Replacing A For loop with an iterative method makes the code readable and avoids repetitive loop control logic

    • Use a custom iteration function to abstract common looping patterns that are not supported by the standard library

    • It is still recommended to use a traditional loop in case of premature termination of the cycle. In addition, the some and every methods can also be used to exit early

Related reading
    • 11th: Master Closure

    • 42nd: Avoid using rash monkey patches

[Effective JavaScript notes] 50th: Iterative methods are better than loops

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.