引子: js必须要了解他的闭包

https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example

https://stackoverflow.com/questions/111102/how-do-javascript-closures-work/111111#111111

闭包

谈到了函数就不能不谈闭包, 这个是js特色, 为啥用闭包? 其实是为了封闭对象的私有属性.

为啥用闭包, 这个实在是忘记了, 还要再看一下下, 为啥不是简单的使用函数, 而是要用闭包.

  1. 明白了, 闭包拥有可以访问私有属性的方法了.
  2. 闭包返回一个对象更有意义, 一般情况下.
  3. 这个对象可以访问闭包函数拥有的私有属性, 这些属性外部无法访问.
  4. 如果我就是定义一个函数, 用来返回对象, 那么我还要执行这个函数. 来得到他返回的对象, 因此, 这个函数的函数名就毫无意义, 把定义这个函数和执行这个函数合二为一之后, 就是闭包了.
  5. 闭包其实就是直接执行一个函数, 得到返回的对象, 这个对象还有自己的私有属性, 这些属性定在了这个直接执行的闭包函数里面.
闭包的实际案例

https://stackoverflow.com/questions/3288893/why-do-we-have-closures-in-javascript

  1. module 可以做分包, 参见我8.28的blog
  2. 可以memorization, 简单地说就是缓存计算结果 参见我8.29的blog
  3. currying, 递归和迭代
let和闭包

let确实在很多时候可以替代闭包. 尤其是:

  1. timeout这一类的异步执行.
  2. 循环体里面执行函数, 循环值是函数的参数. 如果不用let也不用闭包, 最后只有循环的最后一个值传入了.
var funcs = [];
for (var i = 0; i < 3; i++) {      // let's create 3 functions
  funcs[i] = function() {          // and store them in funcs
    console.log("My value: " + i); // each should log its value. 
  };
}
for (var j = 0; j < 3; j++) {
  funcs[j]();                      // and now let's run each one to see
}

//实际输出:
My value: 3
My value: 3
My value: 3

分析:

 function() {          // 这里并没有传入参数.
    console.log("My value: " + i); //  这是一个函数, 这个函数, 里面的i就是一个变量, i最终的值就是3.
  };

//即便改为下面这样也是不行的:
funcs[i] = function(i) {          // and store them in funcs
    console.log("My value: " + i); // each should log its value.
};
//原因是调用的时候, 并没有传入i.   

My value: undefined
My value: undefined
My value: undefined

解决方案有三个, 大家看原文吧, 确实是很精妙: https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example

关于闭包之前的blog有不少:
  1. 17 - 12 - 03 js精华
  2. 17 - 12 - 16 对象和迭代
  3. 17 - 12 - 19 node
  4. 18 - 05 - 17 多语言
  5. 18 - 08 - 28 js模块化
  6. 18 - 09 - 02 js生命
2019-01-19对闭包更多的思考
  1. 当年的js没有module, 没有promise, 没有let, 只有闭包.
  2. 闭包确实是funcitonal的思路, 很容易构造高阶函数, 而且还很规整.
  3. 闭包一定程度上缓解了括号地狱. 但是括号有害这个观点是python之后才出现的. 而在当年, 像lisp一样去构建高阶函数会被认为是一个很优雅的事情, 就像后来出现的那个傻乎乎的addlistener一样. 很多时候, 人们很难分清改进和改退, 马克思说失误曲折发展, 真的很对.