译文开始前的说明:
关于闭包, 译者这个前端新人一直都是怀着敬畏的心仰视着. 每次搜索相关资料, 都有太多太多的信息可以在百度上搜到, 然而看过依然感觉身体有一部分还在云雾之中, 心中感觉不是很踏实. 近日机缘巧合看到一篇 10 年前发布在 stack overflow 上的关于闭包的高分回答, 觉得非常受用.
个人感觉, 其解释说明不似死板背书, 亦有诸多代表性的实例配合理解, 既深入到最基本的原理去解释, 也扩展开去讲解一些实际运用中的方面. 故硬着头皮翻译了一下, 人生中除了毕业论文里面翻译过一篇文献, 这便是自己的 "处女译" 了.
因为此文只是一篇回答, 并非专业的文献或者书籍, 作者有些地方还是显得比较随意, 所以最好带着脑子去思考, 作者很多地方只是提供了一个理解的思路和方向. 另外文中有些地方作为一个新手小白可能没能理解透彻, 甚至误解, 希望大家踊跃批评, 感谢!
- function sayHello(name) {
- var text = 'Hello' + name;
- var say = function() { console.log(text); }
- say();
- }
- #### 闭包的一个栗子
- function sayHello2(name) {
- var text = 'Hello' + name; // Local variable
- var say = function() { console.log(text); }
- return say;
- }
- var say2 = sayHello2('Bob');
- say2(); // logs "Hello Bob"
- function say667() {
- // Local variable that ends up within closure
- var num = 42;
- var say = function() { console.log(num); }
- num++;
- return say;
- }
- var sayNumber = say667();
- sayNumber(); // logs 43
- var gLogNumber, gIncreaseNumber, gSetNumber;
- function setupSomeGlobals() {
- // Local variable that ends up within closure
- var num = 42;
- // Store some references to functions as global variables
- gLogNumber = function() { console.log(num); }
- gIncreaseNumber = function() { num++; }
- gSetNumber = function(x) { num = x; }
- }
- setupSomeGlobals();
- gIncreaseNumber();
- gLogNumber(); // 43
- gSetNumber(5);
- gLogNumber(); // 5
- var oldLog = gLogNumber;
- setupSomeGlobals();
- gLogNumber(); // 42
- oldLog() // 5
- function buildList(list) {
- var result = [];
- for (var i = 0; i < list.length; i++) {
- var item = 'item' + i;
- result.push( function() {console.log(item + ' ' + list[i])} );
- }
- return result;
- }
- function testList() {
- var fnlist = buildList([1,2,3]);
- // Using j only to help prevent confusion -- could use i.
- for (var j = 0; j < fnlist.length; j++) {
- fnlist[j]();
- }
- }
- testList() //logs "item2 undefined" 3 times
- pointer = function() {console.log(item + ' ' + list[i])};
- result.push(pointer);
- function sayAlice() {
- var say = function() { console.log(alice); }
- // Local variable that ends up within closure
- var alice = 'Hello Alice';
- return say;
- }
- sayAlice()();// logs "Hello Alice"
- function newClosure(someNum, someRef) {
- // Local variables that end up within closure
- var num = someNum;
- var anArray = [1,2,3];
- var ref = someRef;
- return function(x) {
- num += x;
- anArray.push(num);
- console.log('num:' + num +
- '\nanArray' + anArray.toString() +
- '\nref.someVar' + ref.someVar);
- }
- }
- obj = {someVar: 4};
- fn1 = newClosure(4, obj);
- fn2 = newClosure(5, obj);
- fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
- fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
- obj.someVar++;
- fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
- fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;
来源: http://www.qdfuns.com/article/31628/0e179cfaf975e0657fca1178e085e6c7.html