昨天开始学习js里的设计模式,这里特别推荐一本书《JavaScript设计模式与开发实践》,这本书是腾讯前端大神写的,讲的非常好,有实际当中的应用场景,还有讲了怎样用,什么地儿用,这位森赛讲的很好。
但是在阅读当中呢有一些地方还不太明白(我比较菜),然后又了了汤姆大叔的"深入理解JavaScript"这个系列博客,其中大叔有提到设计模式,读起来比起前面提到这本书讲的更好理解一些。
下面贴出我的笔记和代码:
//单例模式
//一个类,只产生一个实例,而且可以全局访问
//不透明的单例模式。 因为用之前不知道它这个类是个单例
var Singleton = function(name) {
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function() {
console.log('test');
};
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');
//这时候你去拿b的name 还会显示sven1
//还可以这样写
var Singleton2 = function(name) {
this.name = name;
};
Singleton2.prototype.getName = function() {
console.log(this.name);
};
Singleton2.getInstance = (function() {
var instance = null;
return function (name) {
if (!instance) {
instance = new Singleton2(name);
}
return instance;
}
})();
//透明的单例.在页面中创建唯一的一个节点
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 CreateDiv2 = function(hmtl) {
this.html = html;
this.init();
};
CreateDiv2.prototype.init = function() {
var div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
};
var ProxySingletonCreateDiv = (function() {
var instance;
return function (html) {
// body...
if (!instance) {
instance = new CreateDiv2(html);
}
return instance;
}
})();
//这样子搞就是跟方便一点 你可以用creatediv2这个类创建许多实例, 也可以可代理类结合
//搞出一个单例模式出来
//以上是传统的单例实现方法,基于类的,但是因为js是class-free类型 语言(虽然es6添加了class这个概念)
//所以在JS开发环境中具体实现的单例模式还不太一样
//最简单的,可以这样搞
var mySingleton = {
property1: "something",
property2: "something else",
method1: function () {
console.log('hello world');
}
};
//复杂一些的,可以拓展功能的
var mySingleton = function () {
/* 这里声明私有变量和方法 */
var privateVariable = 'something private';
function showPrivate() {
console.log(privateVariable);
}
/* 公有变量和方法(可以访问私有变量和方法) */
return {
publicMethod: function () {
showPrivate();
},
publicVar: 'the public can see this!'
};
};
var single = mySingleton();
single.publicMethod(); // 输出 'something private'
console.log(single.publicVar); // 输出 'the public can see this!'
//下面是惰性单例(需要的时候,再创建对象)的实现
//一个悬浮登陆框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>loginBtn</title>
</head>
<body>
<button id="loginBtn">登陆</button>
</body>
<script>
var createLoginLayer = (function() {
var div;
return function () {
if (!div) {
var div = document.createElement('div');
div.innerHTML = "登陆浮窗";
div.style.display = 'none';
document.body.appendChild(div);
}
return div;
}
})();
document.getElementById('loginBtn').onclick = function () {
var loginLayer = createLoginLayer();
loginLayer.style.display = 'block';
};
</script>
</html>
//以上仍不是通用的惰性单例模式
//see? 我们抽出惰性单例通用的逻辑
var obj;
if ( !obj ){
obj = xxx;
}
//我们可以把它抽象成一个函数
//fn是创建对象的方法,result保存对象,因为它在闭包中 所以不会被销毁。
//getSingleton 这个方法来管理单例
var getSingleton = function(fn) {
var result;
return function () {
return function() {
return result||(result = fn.apply(this, [arguments]));
};
}
};
var createLoginLayer = function() {
var div = document.createElement('div');
div.innerHTML = '我是登录浮窗';
div.style.display = 'none';
document.body.appendChild(div);
return div;
};
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('loginBtn').onclick = function() {
var loginLayer = createSingleLoginLayer();
loginLayer.style.display = 'block';
};
以上就是单例的笔记与总结。
网友评论