《SPA设计与架构》之JavaScript模块化
原文
简书原文:https://www.jianshu.com/p/d5fc38506bc4
大纲
1、什么是模块?
2、基本的模块模式
3、模块模式概念
4、模块结构
5、揭示模式
6、模块编程的意义
7、模块化编程的重要性
1、什么是模块?
通常模块(Module)是指某个更大结构的一部分或组件。然而,模块术语依据不同上下文,甚至在软件开发范畴内,都可以用不同含义。有时我们会听到人们在一般意义层面讨论模块。比如,他们可能说“支付模块”或者“旅行计划模块”。这时候模块意指整体特性是完全没有什么问题的。而在我们特指JavaScript代码块的时候,模块就代表一个函数——一个通过模块模式创建的特定函数。
2、基本的模块模式
3、模块模式概念
3.1、命名空间
命名空间是一种为一组相关成员提供具体作用域的方式。尽管命名空间当前并非JavaScript语言的一部分,但仍可以通过为更大作用域的任何变量(如全局变量)分配模块函数来达到同样效果。
3.2、匿名函数表达式
函数表达式是表达式的一部分,且不以function关键字开头。如果函数表达式未命名,则被称为匿名函数表达式。模块体包含在一个匿名函数表达式当中。
3.3、对象字面量
JavaScript提供了一种创建对象的快捷方式,被称为字面量标记法,其通过花括号声明一个对象,它的Property用键值对来表示。
3.4、闭包
通常,当函数执行完毕,在其中创建的任何局部变量的生命周期也就宣告结束。闭包则是一个例外情况,当函数包含了外层作用域的变量引用时,例外就发生了。在JavaScript中,每个函数也都有一个外层作用域,即使外层作用域恰好就是全局作用域(所以从技术角度来讲,所有函数都是闭包)。闭包对于我们的讨论内容是非常重要的,因为即使模块模式的外层函数立即执行完毕,只要模块仍在使用,外层函数返回语句所引用作用域链之上的任何对象或值,都无法被垃圾回收。
4、模块结构
模块结构巧妙地使用一个函数作为封装其逻辑的容器。这是可能的,因为在模块中局部声明变量及函数可以避免模块外部直接访问它们。模块内部功能的访问可以通过访问语句暴露的内容来控制。
5、揭示模式
模块模式的吸引力之一就是在模块内部功能与公开功能之间划定了清晰的界限。有一种频繁用到并能够让划分更加清晰的改良版模块模式——揭示模式(revealing module pattern)。
其实现思路是:将任何API所需代码移到内部,将公有函数作为纯粹指向内部代码的指针,并只暴露该公有函数。
6、模块编程的意义
6.1、避免命名冲突
不用模块限制函数作用域,把函数一股脑地放进全局作用域,将很容易导致命名冲突
模块模式能够让你按自己意愿命名变量或函数,而不用担心不同模块代码间会产生命名冲突问题
6.2、保护代码完整性
在某些语言中,访问某部分应用程序代码可以通过注入public或private这样的访问修饰符来控制。而在JavaScript中private是保留关键字。我们仍然可以通过模块模式限定变量和函数的访问权限。这是可能的,因为在某个函数里声明的变量和函数,意味着它们的作用域已限制为容器函数。这种限制访问某部分模块代码的能力将组织其他代码直接改变其内部状态,维系模块内部正常运作,并避免模块数据遭到肆意修改导致违背其预期目的。
正确编写安全的代码难度很大。如果你无法阻止代码内逻辑的错误使用,编写安全代码的希望就愈发渺茫。模块模式提供了一种管理内部代码访问性的方式。
6.3、隐藏复杂性
当讨论隐藏编程复杂度时,并非说我们想讨论如何保守秘密或者如何增加安全性。我们要讨论的是两种方式的差异性:通过大量全局函数实现具体功能的复杂逻辑,以及将复杂逻辑放至内部并只通过公有接口暴露开发者所需功能。后者减少了混乱,并使得函数调用更加清晰起来,以正确使用应用功能。
7、模块化编程的重要性
模块化编程最重要的思想:通过模块模式来内化逻辑复杂性并提供功能对应公有API,这是JavaScript的封装实现方式。
模块化的代码能够将应用逻辑组织成单一目标的更小单元,其更容易管理及修改。毫无疑问这带来了更好的可重用性。模块还有助于保持数据完整性、代码组织以及避免命名冲突。毕竟我们为无刷新的单一页面编写代码,如果不按这种设计方式编写代码,纯粹依赖全局变量和函数的话,代码将很快变得难以管理。