gistfile1.txt function lazy_sum(arr) { var sum = function () { return arr.reduce(function (x, y) { return x + y; }); } return sum;}//当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数var f = lazy_sum([1, 2, 3
function lazy_sum(arr) { var sum = function () { return arr.reduce(function (x, y) { return x + y; }); } return sum; } //当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数 var f = lazy_sum([1, 2, 3, 4, 5]); // function sum() //调用函数f时,才真正计算求和的结果 f(); // 15 //当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数: var f1 = lazy_sum([1, 2, 3, 4, 5]); var f2 = lazy_sum([1, 2, 3, 4, 5]); f1 === f2; // false //f1()和f2()的调用结果互不影响。 //返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。 //比如下面的写法 function count() { var arr = []; for (var i=1; i<=3; i++) { arr.push(function () { return i * i; }); } return arr; } var results = count(); var f1 = results[0]; var f2 = results[1]; var f3 = results[2]; f1(); // 16 f2(); // 16 f3(); // 16 //三个函数调用都是16 //原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了4,因此最终结果为16。 //如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变: function count() { var arr = []; for (var i=1; i<=3; i++) { arr.push((function (n) { return function () { return n * n; } })(i)); } return arr; } var results = count(); var f1 = results[0]; var f2 = results[1]; var f3 = results[2]; f1(); // 1 f2(); // 4 f3(); // 9 //注意这里用了一个“创建一个匿名函数并立刻执行”的语法: (function (x) { return x * x; })(3); // 9 //闭包在Javascript中能做什么?返回一个函数延迟执行;封装一个私有变量 //在没有class机制,只有函数的语言里,借助闭包,同样可以封装一个私有变量。 'use strict'; function create_counter(initial) { var x = initial || 0; return { inc: function () { x += 1; return x; } } } var c1 = create_counter(); c1.inc(); // 1 c1.inc(); // 2 c1.inc(); // 3 var c2 = create_counter(10); c2.inc(); // 11 c2.inc(); // 12 c2.inc(); // 13 //在返回的对象中,实现了一个闭包,该闭包携带了局部变量x,并且,从外部代码根本无法访问到变量x。换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。 //闭包还可以把多参数的函数变成单参数的函数。例如,要计算xy可以用Math.pow(x, y)函数,不过考虑到经常计算x2或x3,我们可以利用闭包创建新的函数pow2和pow3: function make_pow(n) { return function (x) { return Math.pow(x, n); } } // 创建两个新函数: var pow2 = make_pow(2); var pow3 = make_pow(3); pow2(5); // 25 pow3(7); // 343 //闭包就是能够读取其他函数内部变量的函数。 //在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。 //最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。 function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000 /* "nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。 其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。 */