Page 18 - JavaScript修炼之道
P. 18

4       第一部分  JavaScript 必备操作



             任务 2  通过模块模式实现代码访问控制


                 随着你的JavaScript代码库的扩大,本应被控制在私有作用域中的函数和变量将会被暴露得越
             来越多,这时你的全局作用域被“污染”的可能性就会越来越大。这不仅会导致命名冲突(此处
             的脚本在无意中覆盖了其他脚本中的标识符),也会为bug提供了温床。

                 因此,我们需要编写自包含的、不透明的JavaScript代码,它不会向外界暴露内部的细节,也
             不会与现有的框架和库出现冲突。事实上,这正是“大规模编程”的主要要求。模块模式正是由
             此应运而生的。

                 模块模式的主要思想,是为那些通过var关键字声明的标识符和函数创建一个私有作用域,只
             有定义在这个作用域里的函数才能直接访问这些数据。为了使外界能够访问到函数里的部分内容,
             我们有两个选择。其一是返回一个包含选定值的对象(具体的做法见右页中的代码),然后把这个
             对象赋给外界的变量;另一种则是给函数传入一个外部作用域可访问的对象作为参数,使该函数能
             在这个对象中写入自己的属性(如果想让它的属性成为全局属性,只需传入window对象)。

                 JavaScript中,使用var关键字声明的标识符是局部的(它们只属于当前定义的作用域)。而
             未使用var关键字声明的标识符是全局的(它们会被嫁接到当前的默认作用域,而默认作用域在
             多数情况下就是全局的window对象)。

                 在一些特殊情况下,当前的默认域可能不是全局的,在这样的上下文中,即使使用非var声
             明的标识符,也不会对全局命名空间造成影响。不过,这已经超出了本任务所讨论的范围。

                 技术上来说,你并不需要像命名私有标识符那样显示命名“公有属性”。事实上,你完全可
             以在返回的对象中用匿名函数的方式定义公有方法。但这样做的话会使得代码晦涩难懂(或是

             带有误导性),更重要的是,这会使调试难以进行。因此,尽可能用命名函数表达式来定义你的
             函数:

                 function myFunctionName(...) { ... }

                 这会令代码更加清晰,同时也便于在调试时观察栈轨迹。
   13   14   15   16   17   18   19   20   21   22   23