要理解闭包,首先要先理解javascript变量的做用域 变量的做用域只有两种:全局变量 + 局部变量javascript
全局变量:任何地方均可以访问(函数内部、外部) 局部变量:只能在变量所在函数及函数的子函数中访问 :fa-exclamation-circle:注意:变量声明若是不使用var关键字,那么他就是一个全局变量,即便是在函数内部定义java
但愿计算器的值counter可以被修改,可是不但愿被任意更改(只能+1) 全局变量实现:闭包
var counter = 0; function add(){ ++counter; } add(); //1 add(); //2 add(); //3 问题:counter的值能够被任意更改。
局部变量实现:函数
function add(){ var counter = 0; ++counter; } add(); //1 add(); //1 add(); //1 问题:counter的值不能按照设想来正确输出。
javascript的闭包就能够解决该问题。性能
在javascript中,全部的函数都可以访问它们上层的做用域code
function add(){ var counter = 0; function plus(){ ++counter; } }
上面代码中,plus函数在add函数内部,这使得add内部的全部局部变量都是对plus可见的,可是反过来却不行。 这就是javascript语言特有的【链式做用域】结构(chain scope)ip
若是咱们可以在外部访问plus函数,那么这个【计算机困境】就可以解决了 因此,只要将plus函数做为add函数的返回值,就能够访问plus函数了, 也就能够经过plus函数,在add函数外部访问add函数局部变量了内存
================ 以上所说就是闭包。ci
当函数a的内部函数b被函数a外的一个变量引用的时候,就建立了一个闭包。 闭包就是将函数内部和函数外部链接起来的一座桥梁作用域
计算机困境能够更改成如下两种方式:
1:(建议) var add = (function(){ var counter = 0; return function plus(){return ++counter;} })(); add(); //1 add(); //2 add(); //3 2: function add(){ var counter = 0; return function plus(){return ++counter;} } var f1 = add(); f1(); //1 f1(); //2 f1(); //3
以上证实:局部变量counter一直在内存中, 并无在函数执行完后自动清除。 why?????? because: --add是plus的父函数,而plus被赋给了一个全局变量,致使plus始终在内存中, 而plus函数依赖于add函数,因此add也一直在内存中,不会再结束后被GC回收。
function add(){ var counter = 0; getCounter = function(){ reutrn counter; } }
注意add中的getCounter变量,由于没有使用var来声明,因此它是一个全局变量, 能够当作java中的getter来使用 :fa-hand-o-down:
public class add{ private int counter = 0; public int getCounter(){ return counter; } }