js单例模式

来源:互联网 发布:淘宝怎么修改认证信息 编辑:程序博客网 时间:2024/05/16 09:12

设计模式 :复用别人总结的解决问题的经验




单例模式:保证一个类只有一个实例 并提供一个访问他的全局访问点



看一个例子

// function Minister(name) { // 大臣//     this.name = name;// }// Minister.prototype.say = function () {//     console.log(this.name + ':大王,冤枉啊!');// };// function Emperor() { // 皇帝//     this.name = '大王';//     this.id = Math.random();// }// Emperor.prototype.say = function () {//     console.log(this.name + this.id + ':滚……');// };// var minister1 = new Minister('张三');// var emperor1 = new Emperor();// var minister2 = new Minister('李四');// var emperor2 = new Emperor();// var minister3 = new Minister('王二麻子');// var emperor3 = new Emperor();// minister1.say();// emperor1.say();// minister2.say();// emperor2.say();// minister3.say();// emperor3.say();

这里的大王id每次实例都在变化    不是很友好


如何修改?


// function Minister(name) { // 大臣//     this.name = name;// }// Minister.prototype.say = function () {//     console.log(this.name + ':大王,冤枉啊!');// };// function Emperor() { // 皇帝//     this.name = '大王';//     this.id = Math.random();// }// Emperor.prototype.say = function () {//     console.log(this.name + this.id + ':滚……');// };// Emperor.getInstance = (function () {//     var instance = null;//     return function () {//        if (!instance) {//           instance = new Emperor();//        }//        return instance;//     };// })();// var minister1 = new Minister('张三');// var emperor1 = Emperor.getInstance();// var minister2 = new Minister('李四');// var emperor2 = Emperor.getInstance();// var minister3 = new Minister('王二麻子');// var emperor3 = Emperor.getInstance();// minister1.say();// emperor1.say();// minister2.say();// emperor2.say();// minister3.say();// emperor3.say();
这样修改后的id每次都是一样的了  但是有个问题  instance可能会被外部修改

但是如果我想正常的new出一个实例呢?

function Minister(name) { // 大臣   this.name = name;}Minister.prototype.say = function () {   console.log(this.name + ':大王,冤枉啊!');};var Emperor = (function () {   var instance = null;   function Emperor() {      if (instance) {         return instance;      }      this.name = '大王';      this.id = Math.random();      return instance = this;   }   Emperor.prototype.say = function () {      console.log(this.name + this.id + ':滚……');   };   return Emperor;})();var minister1 = new Minister('张三');var emperor1 = new Emperor();var minister2 = new Minister('李四');var emperor2 = new Emperor();var minister3 = new Minister('王二麻子');var emperor3 = new Emperor();minister1.say();emperor1.say();minister2.say();emperor2.say();minister3.say();emperor3.say();



问:getInstance方法该如何理解呢?

getInstance()它可以把一个已存在的引用给你使用,getInstance()可以跨栈区域使用,或者远程跨区域使用。所以getInstance()通常是创建static静态实例方法的。跟new的功能差不多,但是又不一样,这个仅作了解即可,开发中我们用new创建对象比较多一些。.

.



具有js特色的单例模式

看一下例子

假如这个代码很长

有其他人要修改的时候 声明了一个getById 与你之前声明的函数名冲突 就会产生bug


所以要用单例模式

例如这里的Alex  和zhangsan


单例的优点  :1.每个修改的人都创建了一个命名空间 这样就不会产生冲突


2.使代码井井有条




惰性单例

按需创建的单例







<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8" /><title>具有JavaScript特色的单例模式--惰性单例</title><style>   body {      background-color: #f0f0f0;   }   #loginLayer {      position: absolute;      left: 240px;      top: 80px;      z-index: 2;      width: 200px;      height: 200px;      border: 1px solid #ccc;      background-color: #fff;      text-align: center;   }   #maskLayer {      position: absolute;      left: 0;      top: 0;      width: 100%;      height: 100%;      background-color: #000;      opacity: 0.3;   }</style></head><body>   <button id="loginBtn">登录</button><!-- <div id="loginLayer">登录窗口</div><div id="maskLayer"></div> --><script>   
// 通用惰性单例
function createLoginLayer() {   var loginLayer = document.createElement('div');   loginLayer.id = 'loginLayer';   loginLayer.innerHTML = '登录窗口';   loginLayer.style.display = 'none';   document.body.appendChild(loginLayer);   return loginLayer;}function createMaskLayer() {   var maskLayer = document.createElement('div');   maskLayer.id = 'maskLayer';   maskLayer.style.display = 'none';   document.body.appendChild(maskLayer);   return maskLayer;}function getSingleton(fn) {//专门实现单例   var instance = null;   return function () {      return instance || (instance = fn.apply(null, arguments));//有些函数需要传参 所以改写为这样  null表示不改变this   };}var createSingletonLoginLayer = getSingleton(createLoginLayer);var createSingletonMaskLayer = getSingleton(createMaskLayer);document.getElementById('loginBtn').onclick = function () {   var loginLayer = createSingletonLoginLayer();   var maskLayer = createSingletonMaskLayer();   loginLayer.style.display = 'block';   maskLayer.style.display = 'block';};
</script></body></html>


原创粉丝点击