浏览 2810 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-04-07
什么是闭包(closures): 闭包就是内部函数通过某种方式使其可见范围超出了其定义的范围,这就产生了一个在其定义范围内的闭包. 这是我理解后的一个定义,呵呵!很晦涩吧!不过没关系,可以先看看下面的讲解. 一 内部函数(inner function) javascript是支持内部函数申明(inner function declaration)的编程语言, 内部函数就是在另一个函数的内部定义,如 function outerFun(){ function innerFun(){ alert('hello'); } } 函数innerFun就是内部函数, 它在函数outerFun范围内是可见的, 也就是说innerFun函数的命名空间(namespace)是在outerFun范围之内. 正确调用: function outerFun(){ function innerFun(){ alert('hello'); } innerFun(); } outerFun(); //alerts "hello" 错误调用(error): function outerFun(){ function innerFun(){ alert('hello'); } } innerFun(); 那么如果我想在函数outerFun外面调用函数innerFun,我该如何做呢? 做法1: var globVar; function outerFun() { function innerFun() { alert('hello'); } globVar = innerFun; } outerFun(); globVar(); 做法2: function outerFun() { function innerFun() { alert('hello'); } return innerFun ; } var globVar = outerFun(); globVar(); 做法3: function outerFun() { function innerFun() { alert('hello'); } return {'innerFun':innerFun} ; } var globVar = outerFun(); globVar.innerFun(); 以上三种做法把内部函数的可见范围扩大了, 其中最后一种做法是把内部函数当做匿名对象{'innerFun':innerFun}的属性,并随之一起返回. 从中看到在javascript里面,函数名称可以当作是一种引用变量,类似于c里面指针的概念,在这里,随着程序的执行 会产生两个引用变量指向内部函数innerFun,一个是globVar(第三种做法是globVar.innerFun),另一个是其函数自身innerFun, 只不过这两个变量的可见范围不一样,即命名空间不一样. javascript垃圾回收器会在函数最后一个引用变量被废弃后,释放其所占用的内存. 二 变量范围 例1 内部函数变量 在内部函数内申明的变量其可见范围就在其函数内 function outerFun() { function innerFun() { var innerVar = 0; innerVar++; alert(innerVar); } return innerFun; } var globVar = outerFun(); globVar(); // Alerts "1" globVar(); // Alerts "1" var innerVar2 = outerFun(); innerVar2(); // Alerts "1" innerVar2(); // Alerts "1" 每一次内部函数调用,一个新的innerVar变量都被创建,所以结果显示都是1 例2 内部函数引用全局变量(global variables) var globVar = 0; function outerFun() { function innerFun() { globVar++; alert(globVar); } return innerFun; } var globVar = outerFun(); globVar(); // Alerts "1" globVar(); // Alerts "2" var globVar2 = outerFun(); globVar2(); // Alerts "3" globVar2(); // Alerts "4" 每一次内部函数的调用,全局变量都增加1,所以显示结果都是依次递增. 例3 内部函数引用外部函数变量 function outerFun() { var outerVar = 0; function innerFun() { outerVar++; alert(outerVar); } return innerFun; } var globVar = outerFun(); globVar(); // Alerts "1" globVar(); // Alerts "2" var globVar2 = outerFun(); globVar2(); // Alerts "1" globVar2(); // Alerts "2" 注意在第2次调用outerFun()的时候重新创建了一个新的变量outerVar,所以显示结果是"1","2","1","2" 什么是闭包(closures)呢, 就是内部函数通过某种方式使其可见范围超出了其定义的范围, 如上例3,globVar 就是函数outerFun()的一个闭包, 而闭包产生的时机就是这句代码var globVar = outerFun(); 再看上例3,闭包globVar第一次调用之后,变量outerVar 值 "1" 还是在内存 中,没有回收,因为闭包globVar第二次调用的时候其值已经递增为"2" ,只要globVar没有被废弃掉,则outerVar的值就会一直存在. 像outerVar 这样的变量称其为自由变量 三 闭包与面向对象编程之间的联系 看看下面的例子: function outerFun() { var outerVar = 0; function innerFun() { outerVar++; alert(outerVar); } function innerFun2() { outerVar = outerVar + 2; alert(globVar); } return {'innerFun': innerFun, 'outerFun2': outerFun2}; } var globVar = outerFun(); globVar.innerFun(); // Alerts "1" globVar.innerFun2(); // Alerts "3" globVar.innerFun(); // Alerts "4" var globVar2 = outerFun(); globVar2.innerFun(); // Alerts "1" globVar2.innerFun2(); // Alerts "3" globVar2.innerFun(); // Alerts "4" outerFun()可以看成是类,globVar,globVar2可以看成是两个实例,实例变量就是outerVar,并且是private. 函数innerFun(), innerFun2()就是实例方法. 可能这还不是很清楚,在看下面的例子: function Boy(){ var name; function setName(vName){ name = vName; } function getName(){ return name; } return {'setName': setName, 'getName': getName}; } var boy1 = Boy(); boy1.setName("zhuzhenhua"); alert(boy1.getName()); 写到这里,仍然对闭包这个概念所对应的物理结构有些模糊,所以还请过路的侠士指点一二. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-04-08
朋友,帖子放错地方! 建议你重新编辑一下,保持论坛内容的统一性.
|
|
返回顶楼 | |