「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。
正文
在JavaScript中,单例模型的运用可以说十分广泛,就好比一个按钮,点击它弹出一个登录浮窗,不管用户点击多少次。这个浮窗也只会被创建一次,那么这个登录浮窗就适合用单例模式来创建
4.1实现单例模式
要创建一个简单的JavaScript单例模式并不复杂,创建一个对象来标志着对某个类创建一个对象,如果该对象存在,则无法创建新的对象,我们用一段代码来解释一下
var Singleton = function( name ){
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function(){
alert ( this.name );
};
Singleton.getInstance = function( name ){
if ( !this.instance ){
this.instance = new Singleton( name );
}
return this.instance;
};
var a = Singleton.getInstance( 'sven1' );
var b = Singleton.getInstance( 'sven2' );
alert ( a === b ); // true
虽然我们完成了一个单例模式的编写,但是意义不是很大,因为它具有“不透明性”,Singleton类必须让使用者知道这是一个单例类,接下来我们来创建一个具有透明性的单例模式
4.2透明的单例模式
这段代码的作用是创建一个具有透明性的单例类,CreateDiv单例类的作用是为页面创建一个唯一的div节点
var CreateDiv = (function(){
var instance;
var CreateDiv = function( html ){
if ( instance ){
return instance;
}
this.html = html;
this.init();
return instance = this;
};
CreateDiv.prototype.init = function(){
var div = document.createElement( 'div' );
div.innerHTML = this.html;
document.body.appendChild( div );
};
return CreateDiv;
})();
var a = new CreateDiv( 'sven1' );
var b = new CreateDiv( 'sven2' );
alert ( a === b ); // true
这构造函数喊起来确实很奇怪,运用了匿名函数和闭包,阅读起来不是特别舒服,但他确确实实是一个很经典的单例模式代码,其中CreateDiv负责了两件事情,第一件事情是创建对象并且执行初始化方法init,第二个是保证只有一个对象,但是这种方法不是特别好,至少看起来很奇怪。
JavaScript中的单例模式
前面所讲的单例模式接近与原生的比较传统,就像面向对象语言中实现一样,但是JavaScript是一门无类语言,生搬这些代码显得毫无意义,既然我们只需要一个对象,何必为它再创建一个类呢?
单例模式的核心是确保只有一个实例,并且提供全局访问。
就像 var a = {} 一样如果a定义在全局作用域,那么在全局的任何地方都能访问a,全局变量提供给全局访问是理所应当的,这也就满足了单例模式的两个条件。
但是如果大量得使用全局变量,容易造成全局污染,哈哈相信大多数前端开发工程师都曾经历过变量冲突的问题,随时可能被自己不小心覆盖掉。。。
JavaScript的开发者也多次谈到这全局变量的问题,他也承认全局变量是开发设计上的失误,是因为没有足够的时间去思考一些东西所导致的结果。
作为普通的开发者,我们要尽可能的避免全局变量的使用,即使需要也要把全局污染的概率降到最低。
介绍一个避免全局污染的方法
1.使用命名空间:
var namespace1 = {
a:function(){
},
b:function(){
}
}
这样写把a和b都设置为namespace1的属性,这样可以减少变量和全局作用域打交道的机会。(让我想起来了vue中组件data为什么是函数)。
今天就到这里,明天我打算给大家讲讲惰性单例