单体就是一个只实例化一次的对象,他可以用来
现在我们来看看单体的最基本的模式
var Jason = {
attribute: true,
method: function () {
// ...
}
}
这种最基本的单体模式可以用delete
方法把属性和方法删掉,如delete(Jason.xxx)
所以我们就应该把我们的私有变量都保护起来,这时就要用到闭包了
使用单体模式来创建命名空间
var Jason = (function () {
// 这里存放私有成员
var privateAttribute = true;
function privateMethod () {
// ...
}
return {
// 这里存放公有成员
publicAttribute: false,
publicMethod: function () {
// ...
}
};
})();
这样我们就创建了一个含有私有成员的命名空间,私有成员不可以再delete
去删除了。当我们调用publicMethod
的时候,就可以用Jason.publicMethod()
这样来调用,而且在公有方法访问外部成员的时候,直接使用名称就可以了,不需要加this
有些很大的模块如果一开始就加载,就会使页面加载得很慢,我们可以等到他使用的时候,再加载
惰性加载单体要借助一个静态方法,之前我们如果想访问一个模块的公有方法的时候,要Jason.publicMethod()
访问,但现在就要Jason.getInstance().publicMethod()
这个调用
getInstance
这个方法检查这个单体是不是已经实例化,如果没有,他将创建这个实例并将他返回,如果已经存在,则直接将他返回
下面我们就拿刚刚那个命名空间的代码做修改(但实际上,像命名空间这样的单体,不需要惰性加载,因为他会立即被用到)
把单体里的所有代码都移到一个叫constructor
的方法中
再声明一个变量uniqueInstance
来标识该单体是否已经实例化
因为uniqueInstance
和constructor
都是外部变量,不可以直接访问,所以要返回一个公有方法getInstance
给对象调用,在这个方法里再判断此单体是否已实例化
var Jason = (function () {
var uniqueInstance;
function constructor () {
// 这里存放私有成员
var privateAttribute = true;
function privateMethod () {
// ...
}
return {
// 这里存放公有成员
publicAttribute = false,
publicMethod: function () {
// ...
}
}
}
return {
getInstance: function () {
if (!uniqueInstance) {
uniqueInstance = constructor();
}
return uniqueInstance;
}
}
})();
这样就可以用Jason.getInstance().publicMethod()
来调用我们的共有方法了