JavaScript Basics (26) closures

Source: Internet
Author: User
Tags closure function definition pow

function as return value

Higher-order functions can also return a function as a result value, in addition to the ability to accept functions as parameters.

Let's achieve a Array sum of the pairs. In general, the function of summing is defined like this:

function sum (arr) {    return arr.reduce (function  (x, y) {        return x + y;< c10/>});} SUM ([///  

But what if you don't need to sum it right away, but in the later code, and then calculate it as needed? You can return the SUM function without returning the result of the summation!

function Lazy_sum (arr) {    varfunction  () {        return arr.reduce (  function  (x, y) {            return x +    y;}); return sum;}

When we call lazy_sum() , we return the SUM function instead of summing the result:

var // function sum () // The result of summing is actually computed when the function f is called: //

In this example, we define the function in the function lazy_sum sum , and the intrinsic function sum can refer to lazy_sum the parameters and local variables of the external function, and when the lazy_sum function is returned sum , the relevant parameters and variables are stored in the returned function, which is called " The program structure of the closure (Closure) has great power.

note again that when we call lazy_sum() , each call returns a new function, even if the same parameter is passed in :

var f1 = Lazy_sum ([1, 2, 3, 4, 5]); var f2 = Lazy_sum ([1, 2, 3, 4, 5//  false

f1()and f2() the results of the call are not affected.

Closed Package

Notice that the returned function references a local variable arr within its definition , so when a function returns a function, its internal local variables are referenced by the new function , so it is not easy to implement them with a simple closure.

Another problem to be aware of is that the returned function is not executed immediately, but only when it is called. f() Let's look at an example:

 function   count () { var  arr = [];  for  (var  i=1; i<=3; I++ function   () { return  i * I;    });  return   arr;}  var  results = count ();  var  f1 = Results[0];  var  F2 = Results[1];  var  f3 = results[2]; 

In the example above, each loop creates a new function, and then adds the 3 created functions to one Array .

You may think that the call f1() , f2() and the f3() result should be 1 ,, but the 4 9 actual result is:

//  - //  - //  -

All of them 16 ! The reason is that the returned function refers to the variable i , but it is not executed immediately. When all 3 functions are returned, the variables they refer to are i already turned 4 , so the end result is 16 .

One thing to keep in mind when returning closures is that the return function does not refer to any loop variables, or to subsequent variables that change.

What if you must refer to a loop variable? The method is to create a function that binds the current value of the loop variable with the parameter of the function, regardless of how the loop variable is subsequently changed, and the value that is bound to the function parameter remains the same:

functioncount () {vararr = [];  for(varI=1; i<=3; i++) {Arr.push (function(n) {return function () {                returnn *N;    }}) (i)); }    returnarr;}varResults =count ();varF1 = Results[0];varF2 = results[1];varF3 = Results[2];f1 (); //1F2 ();//4F3 ();//9

Note that there is a syntax for "create an anonymous function and execute it immediately":

(function  (x) {    return x * x;}) (//  9

In theory, creating an anonymous function and executing it immediately can be written like this:

function return x * x} (3);

However, due to the problem of JavaScript parsing, syntaxerror errors are reported, so you need to enclose the entire function definition in parentheses:

(functionreturn x * x}) (3);

In general, an anonymous function that executes immediately can take the function body apart, which is generally the case:

(function  (x) {    return x * x;}) (3);

So much so that the closure is to return a function and defer execution ?

Of course not! Closures have very powerful features. Give me a chestnut:

In object-oriented programming languages, such as Java and C + +, to encapsulate a private variable inside an object, you can use private a member variable to decorate it.

in the absence class of a mechanism, only the language of the function, with closures, can also encapsulate a private variable. we create a counter with javascript:

function Create_counter (initial) {    var x = Initial | | 0;     return {        function  () {            + =1            ; return x;}}    }

It used to look like this:

var c1 =//  1//  2//  3var c2 = Create_ Counter (Ten//  //  //   )

In the returned object, a closure is implemented that carries the local variables and x that the variables x are inaccessible from external code at all . In other words, a closure is a function that carries state, and its state can be completely hidden from the outside.

closures can also turn multi-parameter functions into single-parameter functions. For example, to calculate XY can be used with a Math.pow(x, y) function, but given the frequent calculation of X2 or x3, we can use closures to create new functions pow2 and pow3 :

function Make_pow (n) {    returnfunction  (x) {        return  math.pow (x, n);}    } // Create two new functions: var pow2 = Make_pow (2); var pow3 = Make_pow (3); Console.log (Pow2 (/   /// 343 
Big Brain Hole Open

A long time ago, there was a handsome man called Alonzo Chow Kit, found that only need to use the function, you can use the computer to achieve the operation, and do not need,, 0 1 2 , 3 These numbers and,,, + - * / these symbols.

JavaScript supports functions, so you can use JavaScript to write these calculations with functions. To try:

' Use strict ';//define the number 0:varZero =function(f) {return function(x) {returnx; }};//define the number 1:varone =function(f) {return function(x) {returnf (x); }};//define addition:functionAdd (n, m) {return function(f) {return function(x) {returnm (f) (N (f) (x)); }    }}//calculate the number 2 = 1 + 1:varboth =Add (one, one);//calculate the number 3 = 1 + 2:varthree =Add (one, both);//calculate the number 5 = 2 + 3:varfive =Add (both, three);//You say it is 3 is 3, you say it is 5 is 5, how do you prove? //Oh, look here://Pass a function to 3 and print it 3 times:(Three (function() {Console.log (' Print 3 times ');})) ();//Pass a function to 5 and print it 5 times:(Five (function() {Console.log (' Print 5 times ');})) ();

JavaScript Basics (26) closures

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.