内容简介:单例就是保证一个类只有一个实例,实现方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。但是有个问题:违反了单一职责原则,不够清晰,所以需要改进一下现在是清晰了,但是还有一个小问题,Window给写死了,作为一个优秀的程序员,肯定要灵活,来来再改进一下。
单例就是保证一个类只有一个实例,实现方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。
代码
单例模式的简单实现
es5
function Window(name) {
this.name = name;
}
Window.prototype.getName = function () {
return this.name;
}
//这是类上的方法,只可以通过类来访问,而不能通过实例来访问
Window.getInstance = (function () {
let instance;
return function (name) {
if (!instance) {
instance = new Window(name);
}
return instance;
}
})();
let w1 = Window.getInstance();
let w2 = Window.getInstance();
console.log(w1 === w2) // --> true
复制代码
es6
class Window {
constructor(name) {
this.name = name;
}
static getInstance() {
if (!this.instance) {
this.instance = new Window();
}
return this.instance;
}
}
let w1 = Window.getInstance();
let w2 = Window.getInstance();
console.log(w1 === w2)
复制代码
缺点:
- 客户端 就是使用这个类的使用者必须知道这是一个单例的类,必须主动调用getInstance方法,使用麻烦
- 并不能真正阻止客户端直接new Window
let w3 = new Window(); let w4 = new Window(); 复制代码
优化过程
透明单例
//透明单例
let Window = (function () {
let window;
let Window = function (name) {
if (window) {
return window;
} else {
this.name = name;
return (window = this);
}
}
return Window;
})();
let w1 = new Window();
let w2 = new Window();
console.log(w1 === w2);
复制代码
- 创建一个this=空对象
- new 关键字,如果返回的是一个对象,那么返回对象
但是有个问题:违反了单一职责原则,不够清晰,所以需要改进一下
//把类的实例的创建逻辑和单例逻辑分开
function Window(name) {
this.name = name;
}
Window.prototype.getName = function () {
console.log(this.name);
}
let CreateWindow = (function () {
let instance;
return function (name) {
if (!instance) {
instance = new Window(name);
}
return instance;
}
})();
let w1 = new CreateWindow('zfpx1');
let w2 = new CreateWindow('zfpx2');
console.log(w1 === w2);
复制代码
现在是清晰了,但是还有一个小问题,Window给写死了,作为一个优秀的程序员,肯定要灵活,来来再改进一下。
function Window(name) {
this.name = name;
}
Window.prototype.getName = function () {
console.log(this.name);
}
let CreateWindow = (function () {
let instance;
return function (name) {
if (!instance) {
instance = new Window(name);
}
return instance;
}
})();
let w1 = new CreateWindow('zfpx1');
let w2 = new CreateWindow('zfpx2');
console.log(w1 === w2);
复制代码
命名空间
1.变量名冲突
2.复杂层次对象的可读性要求
其实我们之前用的jquery并没有把变量都声明在 window上,而是都挂在$对象 jQuery,来,栗子两枚:
$.get();
$.post();
$.ajax();
let $ = {
ajax(){},
get(){},
post(){}
}
let $ = {};
$.define = function (namespace, fn) {
let namespaces = namespace.split('.');
let fnName = namespaces.pop();
let current = $;
for (let i = 0; i < namespaces.length; i++) {
let namespace = namespaces[i];//dom
if (!current[namespace]) {
current[namespace] = {};//{dom:{}}
}
current = current[namespace];
}
current[fnName] = fn;
}
$.define('dom.class.addClass', function () {
console.log('dom.class.addClass');
});
$.define('dom.attr', function () {
console.log('dom.attr');
});
$.define('string.trim', function () {
console.log('string.trim');
});
console.log($) // define、dom、string都挂载上了了
$.dom.class.addClass('title'); // -> dom.class.addClass
$.dom.attr('src'); // -> dom.attr
$.string.trim(' abc '); // -> string.trim
复制代码
单例模式的应用场景
jQuery
只会有一个jQuery实例
if(window.jQuery!=null){
return window.jQuery;
}else{
//init~~~~~~~
}
复制代码
模态窗口
一般网站都会有用户系统,例如我们去淘宝买东西,第一时间需要你先登录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="show-btn">显示登录框</button>
<button id="hide-btn">隐藏登录框</button>
<script>
class Login {
constructor() {
this.element = document.createElement('div');
this.element.innerHTML = (
`
用户名 <input name="username"/>
密码 <input name="password"/>
<input type="submit" value="登录"/>
`
);
this.element.style.cssText = `width:100px;height:100px;position:absolute;left:50%;top:50%;margin-top:-50px;margin-left:-50px;display:none`;
document.body.appendChild(this.element);
}
show() {
this.element.style.display = 'block';
}
hide() {
this.element.style.display = 'none';
}
static getInstance() {
if (!this.instance) {
this.instance = new Login();
}
return this.instance;
}
}
document.getElementById('show-btn').addEventListener('click', function () {
Login.getInstance().show();
});
document.getElementById('hide-btn').addEventListener('click', function () {
Login.getInstance().hide();
});
</script>
</body>
</html>
复制代码
store
redux 整 个应用只有一个仓库,整 个仓库只有一个状态state
//redux 整 个应用只有一个仓库,整 个仓库只有一个状态state
function createStore(reducer) {
let state;
let listeners = [];
function subscribe(listener) {
listeners.push(listener);
}
function getState() {
return state;
}
function dispatch(action) {
state = reducer(state, action);
}
return {
getState,
dispatch,
subscribe
}
}
let reducer = function () {
}
let store = createStore(reducer);
复制代码
今天写到这里,喜欢的可以点赞,同时欢迎抛转,有空再写下总结吧~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First Web Design
Ethan Watrall、Jeff Siarto / O’Reilly Media, Inc. / 2009-01-02 / USD 49.99
Want to know how to make your pages look beautiful, communicate your message effectively, guide visitors through your website with ease, and get everything approved by the accessibility and usability ......一起来看看 《Head First Web Design》 这本书的介绍吧!