本文为阅读《JavaScript设计模式》一书后总结部分内容而得,其中代码示例皆来源于该书。
避免在代码复杂的项目中,所创建的全区变量间互相冲突,比如已经有了一个A属性,在之后为了其他功能,又创建了一个同名的A属性。单体为我们提供了一个命名空间,比如有了单体之后,我在NameSpace空间中创建了一个A,又在NameSpace2控件中创建了一个A,NameSpace.A与NameSpace2.A并不冲突。还有很好的一点,单体只会实例化一次。
//定义单体,假设我们已经创建好了一个空的对象字面量MyNamespace作为命名空间 MyNamespace.Singleton = { constant_1: true, constant_2: 10, method1: function() {}, method2: function() {}, init: function() {} } //调用单体内变量 MyNamespace.Singleton.init();
有的时候,我们并不希望有人对单体内的一些成员进行操作,这时候就要通过闭包来定义私有成员。
//定义单体 MyNamespace.Singleton = (function() { var privateMember1 = "1"; function privateFunction() { ... }; return{ publicMember: "2", publicFunction: function() { ... } } })(); //调用单体内共有成员 MyNamespace.Singleton.publicFunction();
以上单体有一个缺陷,就是在脚本加载时就会当即被创建。如果项目有大量单体需要加载,则初始化所需时间会让人崩溃吧。
所以,我们要想办法,让单体延迟创建,并非脚本加载就创建,而是当我们需要调用单体内的成员时,再创建单体。
创建惰性单体需要以下操作:
举例:
//定义单体 MyNamespace.Singleton = (function() { var uniqueInstance; function constructor() { var privateMember1 = "1"; function privateFunction() { ... }; return{ publicMember: "2", publicFunction: function() { ... } } } return{ getInstance: function() { if (!uniqueInstance) { uniqueInstance = constructor(); } return uniqueInstance; } } })(); //调用单体内共有成员 MyNamespace.Singleton.getInstance().publicFunction();
当我们再不同情况下,需要具有不同的成员的单体时,使用分支。
例子:
MyNamespace.Singleton = (function() { var objectA = { method1: function() { ... }, method2: function() { ... } }; var objectB = { method1: function() { ... }, method2: function() { ... } }; return (sonmeCondition)?objectA:objectB; })();
会导致不同模块间的强耦合,比如在同一个单体中的不同成员可能会用在不同模块中,这样在不同模块中必须调用同一个单体中的成员,导致了不同模块间的变量互相之间还具有一定关系,即强耦合。