对闭包的不同定义:
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); }