function as return value
What if you do not need to sum immediately, but in the later code, as necessary to calculate what to do? You can return the SUM function without returning the result of the summation!
function lazy_sum(arr) { var sum = function () { 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 f = lazy_sum([1, 2, 3, 4, 5]); // function sum()
When the function is called f
, the result of the sum is really computed:
// 15
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, the sum
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]);f1 === f2; // false
Closed Package
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:
// 16f2(); // 16f3(); // 16
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;})(3); // 9
In theory, creating an anonymous function and executing it immediately can be written like this:
function (x) { return x * x } (3);
但是由于JavaScript语法解析的问题,会报SyntaxError错误,因此需要用括号把整个函数定义括起来:
通常,一个立即执行的匿名函数可以把函数体拆开,一般这么写:
(function (x) { return x * x;})(3);
Is the closure meant to return a function and defer execution? Of course not! Closures have very powerful features. For 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) { Span style= "COLOR: #0000ff" >var x = Initial | | 0; return {inc: function () {x + = 1 return x; } }}
var c1 = create_counter();c1.inc(); // 1c1.inc(); // 2c1.inc(); // 3var c2 = create_counter(10);c2.inc(); // 11c2.inc(); // 12c2.inc(); // 13
In the returned object, a closure is implemented that carries the local variables and that the variables are inaccessible x
from external code at all x
. 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) {return function Span class= "params" > (x) {return math.pow (x, n);}} //create two new functions: var pow2 = Make_pow (2); 3);p ow2 (5); //25pow3 (7); //343
JS Closed Package