JavaScript设计模式之单例模式

单例模式又被称为单体模式,是只允许实例化一次的对象类。实现的方法一般是先判断实例中是否存在,如果存在则直接返回,不存在就创建了再返回,这样就确保了一个类只有一个实例对象。在JavaScript中,单例模式作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问改对象。

单例的常见作用:

  • 模块间通信
  • 系统中某个类的对象只能存在一个
  • 保护自己的属性和方法

应用

系统中某个类的对象只能存在一个

  例如,我们要实现点击按钮,弹出一个模态框

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>Documenttitle>
    <style>
        div{
            width:200px;
            height:200px;
            border:1px solid #09f;
            position: absolute;
        }
    style>
head>
<body>
    <input type="button" value="弹窗">
    <script>
        var oBtn = document.querySelector("input"),
        offset = 20, index = 1;
        function Module(pos){
            this.offset = pos || 20;
        };
        Module.prototype.create = function(){
            var oDiv = document.createElement("div");
            oDiv.style.left = (++index) * offset + 'px';
            oDiv.style.top = (++index) * offset + 'px';
            oDiv.innerHTML = '普通弹窗';
            return oDiv;
        };
        oBtn.onclick = function(){
            var oDiv = new Module();
            document.body.appendChild(oDiv.create());
        };
    script>
body>
html>

我们希望的是,不管点击按钮多少次,都只出现一个模态框,但结果却是下面这样的:

JavaScript设计模式之单例模式_第1张图片

 

 这个时候就需要用单例模式进行改造:

 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>Documenttitle>
     <style>
         div{
             width:200px;
             height:200px;
             border:1px solid #09f;
             position: absolute;
         }
     style>
 head>
 <body>
     <input type="button" value="弹窗1">
     <input type="button" value="弹窗2">
     <script>
         var oBtn = document.querySelectorAll("input"),
         offset = 20, index = 1;
         function Module(pos){
             this.offset = pos || 20;
         };
         Module.prototype.create = function(){
             var oDiv = document.createElement("div");
             oDiv.style.left = (++index) * offset + 'px';
             oDiv.style.top = (++index) * offset + 'px';
             oDiv.innerHTML = '单例模式弹窗';
             return oDiv;
         };
         Module.one = (function(){
             var ins = null, isExist = false;
             return function(pos){
                 if(!ins) ins = new Module(pos);
                 if(!isExist){
                     document.body.appendChild(ins.create());
                     isExist = true;
                 }
             }
         })();
         oBtn[0].onclick = function(){
             Module.one(10);
         };
         oBtn[1].onclick = function(){
             Module.one(10);
         };
     script>
 body>
 html>

在Module.one中通过变量isExist的两种状态和闭包特性控制元素只能被添加一次,就可以实现只能弹出一个模态框的效果了。

保护自己的属性和方法

单例模式经常为我们提供一个命名空间。例如我们使用过的jQuery,单例模式就为它提供了一个命名空间jQuery。

JavaScript设计模式之单例模式_第2张图片

 

 在上面的代码中,因为可用的单词有限,命名十分简单,但是如果后续后其他的同事在维护代码的时候,出现了同名的方法或变量,这里的业务逻辑就会出现问题,此时就需要用命名空间来约束每一个人定义的变量:

JavaScript设计模式之单例模式_第3张图片  JavaScript设计模式之单例模式_第4张图片

 由于对象中的this指代当前对象,所以,上面两种写法是等效的。

你可能感兴趣的:(JavaScript设计模式之单例模式)