























本文收集了多本书里对
JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助。
var fn = f(); // 将函数f 的返回值赋值给变量fn
fn(); // 1
fn(); //2
fn(); //3
function f() {
var cnt = 0;
return function() { return ++cnt; }
}
var fn1 = f1();
fn1(); //1
fn1(); //1
function f1(){
var cnt = 0;
return ++cnt;
}
从表面上来看,闭包是一种具有状态的函数。或者也可以将闭包的特征理解为,其相关的局部变量在函数调用结束之后将会继续存在。
模块
避免使用全局变量
通过实现信息隐藏
//使用了闭包的模块
// 在此调用匿名函数
// 由于匿名函数的返回值是一个函数,所以变量sum 是一个函数
var sum = (function() {
// 无法从函数外部访问该名称
// 实际上,这变成了一个私有变量
// 一般来说,在函数被调用之后该名称就将无法再被访问
// 不过由于是在被返回的匿名函数中,所以仍可以继续被使用
var position = { x:2, y:3 };
// 同样是一个从函数外部无法被访问的私有变量
// 将其命名为sum 也可以。不过为了避免混淆,这里采用其他名称
function sum_internal(a, b) {
return Number(a) + Number(b);
}
// 只不过是为了使用上面的两个名称而随意设计的返回值
return function(a, b) {
print('x = ', position.x);
return sum_internal(a, b); };
}
)();
// 调用
sum(3, 4);
x = 2
7
在利用函数作用域可以封装名称,以及闭包可以使名称在函数调用结束后依然存在这两个特性后,信息隐藏得以实现。
(function() { 函数体 })();
计数器功能的类
function counter_class(init) { // 初始值可以通过参数设定
var cnt = init || 0; // 设置默认参数的习惯做法(参见5.5 节)
// 如有必要,可在此声明私有变量与私有函数
return {
// 公有方法
show:function() { print(cnt); },
up:function() { cnt++; return this; }, // return this 在使用方法链时很方便
down:function() { cnt--; return this; }
};
}
// 使用代码
var counter1 = counter_class();
counter1.show();
0
counter1.up();
counter1.show();
1
var counter2 = counter_class(10);
counter2.up().up().up().show(); // 方法链
13
表达式闭包
JavaScript 有一种自带的增强功能,称为支持函数型程序设计的表达式闭包(Expression closure)。
var sum = function(a, b) { return Number(a) + Number(b); }
//可以省略为
var sum = function(a, b) Number(a) + Number(b);
由于IE9之前的版本对JScript对象和COM对象使用不同的垃圾收集例程,因此闭包在IE的这些版本中会导致一些特殊的问题。具体来说,如果闭包的作用域链中保存着一个HTML元素,那么就意味着该元素将无法被销毁。
function assignHandler(){
var element = document.getElementById("someElement");
element.onclick = function(){
alert(element.id);
};
}
//把element变量设置为null。这样就能够解除对DOM对象的引用,顺利地减少其引用数,确保正常回收其占用的内存。
function assignHandler(){
var element = document.getElementById("someElement");
var id = element.id;
element.onclick = function(){
alert(id);
};
element = null;
}
封闭变量
延续局部变量的寿命
//把img变量用闭包封闭起来,便能解决请求丢失的问题
var report = (function(){
var imgs = [];
return function( src ){
var img = new Image();
imgs.push( img );
img.src = src;
}
})();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。