试着两句话说明白闭包。
JavaScript的闭包是封装变量和方法的一种方式,在没有class关键字的时代,实现了Object-Oriented编程中数据+方法的封装。
开始一个小例子,闭包2要素:1.被方法体封装的变量。2.被方法体封装的方法体。
function f(){
var i = 0;
return{
"add":function(){
i++;
console.log(i);
},
"reduce":function(){
i--;
console.log(i);
},
"show":function(){
console.log(i);
}
}
}
var handle = f();
handle.add();
handle.add();
handle.show();
var handle2 = f();
handle2.show();
node 执行输出是 1,2,2,0。handle1和hangdle2的i是不一样的,说明这两个i不是一个实例。
可以改成Java开发人员熟悉的Object-Oriented写法:
class F{
constructor(){
this.i = 0;
}
add() {
this.i++;
console.log(this.i);
}
reduce() {
this.i++;
console.log(this.i);
}
show() {
this.i++;
console.log(this.i);
}
}
const handle1 = new F();
handle1.add();
handle1.add();
handle1.show();
唯一需要注意下的是这些变量在内存中的管理方式。只需要记住一点,闭包的管理方式类似于java匿名内部对象。执行引擎发现函数的内部函数引用了内部变量,就默认这是一个闭包。执行引擎会创建一个闭包实例,将需要的变量存储进去,这样就能和一般的对象一样使用了。
函数内部能访问到外部上级作用域的变量是因为作用域作用(如:java的类中的方法,能访问类属性)。而函数外部访问函数内部变量则是闭包。在java里面就是public方法对外暴露操作属性值得方法,而在js里面可以用闭包的方式。