[Effective JavaScript note] 27th: encapsulate code using closures instead of strings

Source: Internet
Author: User
Tags benchmark closure

A function is a convenient way to store code as a data structure that can be executed after the code. This makes it possible to abstract expressive higher-order functions such as map and foreach. It is also the core of the JS asynchronous I/O method. At the same time, you can pass the code as a string to the Eval function to achieve the same functionality.
Programmers face a choice: Should the code be represented as a function or a string?
There is no doubt that code should be represented as a function. One important reason for the lack of flexibility in string notation is that they are not closures.

Closure review

Look at the picture below.

The function values of JS contain more information than the code needed to execute when invoking them. and the JS function values are also stored internally that they may reference variables defined in their enclosing scopes. Functions that track variables within the scope they cover are called closures.
Detailed information to the previous "[Effective JavaScript note] 11th: Master closure" view

String Encapsulation Code

Suppose there is a simple function that repeats the user-supplied action multiple times.

function repeat (n,action) {for   (var i=0;i<n;i++) {       eval (action);}   }

This function does not work well in global scope because the Eval function interprets all the variable references in the string that appear as global variables. For example, a script that tests the benchmark execution speed of a function might use the global start and end variables to store the time exactly.

var start=[],end=[],timings=[];repeat ("Start.push" (Date.now ()); F (); End.push (Date.now ()) "); for (Var i=0,n= start.length;i<n;i++) {   timings[i]=end[i]-start[i];}

But the script is fragile. If we simply move the code into a function, then the start and end variables will no longer be global variables.

Function Benchmark () {    var start=[],end=[],timings=[];    Repeat (Start.push (Date.now ()); F (); End.push (Date.now ()) ");    for (Var i=0,n=start.length;i<n;i++) {       timings[i]=end[i]-start[i];    }    return timings;}

This time the repeat function does not have access to the internal variable start,end of the benchmark function. Or in the global space to find the start,end variable, if it is not a good situation, you can follow the error prompt to complete the error location. If there is a start,end variable in the global at this time, the global variable will be modified and the resulting behavior cannot be predicted.

Closure Package Code

Or use the example above, but some of these we use the closed package to handle the code.
Overwrite repeat function, parameter action is a function, not a string

function repeat (n,action) {for   (var i=0;i<n;i++) {       action ();}   }

Overwriting the benchmark function, the script can safely refer to the local variable start,end in the closure, which is passed in with the callback function of the repeat function.

Function Benchmark () {    var start=[],end=[],timings=[];    Repeat (1000,function () {        Start.push (Date.now ());        f ();        End.push (Date.now ());    });    for (Var i=0,n=start.length;i<n;i++) {       timings[i]=end[i]-start[i];    }    return timings;}

Another problem with the Eval function is that some high-performance engines are often difficult to optimize for code in strings because the compiler is not able to get the source code as early as possible to optimize the code in a timely manner. function expressions can be compiled at the same time that their code appears, making it more suitable for standardized compilation.
Other Eval related content can be viewed:
[Effective JavaScript note] 16th: Avoid using eval to create local variables
[Effective JavaScript note] 17th: Indirect call to eval function is better than direct call

Tips
    • Never include a local variable reference in a string when passing a string to the Eval function to execute their API

    • An API that accepts function calls is better than an API that uses the Eval function to execute strings

Appendix: Code full version

Tidy up the code above to generate a code that can test the execution time of any function

function repeat (n,action) {for   (var i=0;i<n;i++) {       action ();}   } Function Benchmark (N,FN) {    var start=[],end=[],timings=[];    Repeat (N,function () {        Start.push (Date.now ());        fn ();        End.push (Date.now ());    });    for (Var i=0,n=start.length;i<n;i++) {       timings[i]=end[i]-start[i];    }    return timings;} Test code function concatstring (A, b) {    return a+b;} Benchmark (10000,function () {concatstring (' 1 ', ' 2 ');}); /General Call Benchmark (10000,concatstring.bind (null, ' 1 ', ' 2 ');//favor Bind method to generate new function

[Effective JavaScript note] 27th: encapsulate code using closures instead of strings

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.