关于JavaScript闭包运用的思考
一、软件开发中模块化的重要性
在面向对象的世界里,类无疑是最重要的概念,她有效地将软件系统中的各个部分进行模块化分离,避免了相互之间的影响。在面向过程的语言开发过程中,时常会发现代码动不动就冗余,动不动就想着去Ctrl-c Ctrl-v,动不动就碰到命名冲突的问题,致使整个软件系统不易于理解,并大大增加了开发难度,难以开发出复杂度高的软件。这就是面向对象思想出现的契机与意义,相信诸位对面向对象的思想也十分熟悉,其核心无非于通过类的角度来描述整个软件系统的业务逻辑,以达到系统模块化,代码复用的目的。类中有一个非常重要的特性,即规定类中哪些内容是公有的,哪些内容是私有的,这对实现模块化意义非凡,倘若没有这些,一切东西都是全局变量,那何来模块划分这一说?
二、JavaScript中实现公有私有
JS与主流面向对象的语言不同,在我看来,JS更像是一门带有面向过程语法的函数式编程语言,是一种多范式的语言。也就是说,你可以把JS程序写成像C语言,也可以写得像面向对象语言,更可以写成想函数式语言,取决于你对问题空间采取什么样的解决方案。
在JS中如果想要实现模块化,首要问题就是解决模块的公有和私有问题,在JS中,使用闭包的特性来完成这一任务。闭包的概念可以简单阐述如下,假设有函数funcA和funcB,funcB在funcA中定义,那么在funcB中就可以使用funcA中定义的变量,因此外部可以通过funcB来操纵funcA中的变量,并且在funcA的生命周期结束后,funcB依然维持着对funcA变量的引用,并且不会被释放,这样的特性就叫做闭包。也许有人就会问了:为什么直接使用funcA来操作funcA中的变量呢?对,的确可以,但是当funcA是一个匿名函数的时候,外部就无法通过显式的方法来调用funcA里边的变量了。Bingo!就是利用这个特性实现了在JS中的private/public,请看如下代码:
1 var JsClass = (function(){ 2 var thisClass, privateVar="I'm private"; 3 privateFunc = function(){alert("I'm private")}; 4 5 thisClass.publicFunc = function(){ alert("I'm public")}; 6 thisClass.publicVar = "I'm public"; 7 8 return thisClass 9 }())
代码清晰明了,通过匿名函数和闭包的性质,我们能够使用JsClass.publicFunc和JsClass.publicVar来访问对外公开的函数和变量,而privateVar,privateFunc则是外部不可见的,即私有成员。
就此,关于JS中的公有私有问题已完美解决,在JS的世界里,许多库都用到了这一特性来达到模块化的目的,典型的即为requirejs,在JS世界里,到处闪耀着函数式编程的星光,等待着你寻找、发现、欣赏。