对闭包的不同定义:

1.这个函数通常被定义在另一个外部函数中,并且引用了外部函数的中的变量。

2.闭包是一种能被调用的对象,它保存了创建它的作用域的信息。

3.将当前上下文中的变量代入定义的匿名方法中。匿名方法中定义的变量,在外部看不到。这种单向的包含关系叫闭包。

4.闭包是可以包含自由变量的代码块,自由变量不在这个代码块或任何全局上下文中定义,而是在定义代码块的环境中定义。

 

闭包的价值在于可以作为函数对象或匿名函数,支持闭包的语言都可以将函数赋值给变量,作为参数或返回值。

JavaScript中的闭包例子:

函数a中定义函数b并返回,外部函数c获取函数b并调用。由于函数a中的变量i可以被外部函数引用,所以一直不释放。

function a() {
    var i=0;
    function b() {
        alert(++i);
    }
    return b;
}
var c=a();
c();

 

Java语言本身并没有实现闭包,但可以用匿名的内部类来模拟闭包。

闭包的作用就是简化了主程序和匿名函数之间变量交换,参数传递的过程,不需要额外定义变量,直接传。容易导致变量得不到释放,因为闭包函数会延长变量的生命周期。

Java使用闭包的场景:

假设有下面的Teacher接口和Programmer类,都提供了work方法,但方法功能不一样。

public interface Teacher{
    void work();
}
public class Programer{

    private String name;

    public Programer() {}

    public Programer(String name) {this.name=name;}

    public String getName(){return name;}

    public void setName(String name){this.name=name;}

    public void wrok() {System.out.println(name+"在干xxx");
}

张三,即使程序员又是教师。也就是需要定义一个类,实现Teacher接口,也需要继承Programmer父类。但问题是都包含了work方法。

通过一个闭包的内部累来实现这个功能:

public class TeacherProgramer extends Programer{

    public TeacherProgramer(){}

    public TeacherProgramer(String name){super(name);}

    public class Closure implements Teacher{

        public void work() {name+"hello word"}

    }

    public Teacher getCallBack() (return new Closure();}
}


public static void main(String[] args){

    TeacherProgramer teacherProgramer=new TeacherProgramer("法外狂徒张三");

    teacherProgramer.work();

    teacherProgramer.getCallback().work();

}

 

自由变量:

在A作用域中使用的变量x,却没有在A作用域中声明(即在其他作用域中声明),对于A作用域来说,x就是一个自由变量。

var x=10;
function fn() {
  var b=20;
  console.log(x+b);
}