zoukankan      html  css  js  c++  java
  • js设计模式——单体模式

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>测试文档</title>
        <script>
    //        单体模式的定义:一个只能实例化一次的类,并且提供一个众所周知的全局访问点。
    //        单体模式的作用:面向对象编程的思考方式,就是对现实生活的具体对象抽象化。————即建模
    // 对于现实生活来说,很多对象只有一个是很重要的。比如说,一个公司只能有一个会计系统,一个数字滤波器只能有一个模数转换器
    //一台计算机只应该有一个文件系统和窗口管理器。对应到抽象的面向对象编程的世界里,就是有些类只应该有一个实例。
    //        单体模式的实现:让类自身负责保存它的唯一实例。(这个类可以保证只能创建一个实例,并且有一个可访问该实例的方法)
    //
    //        单体模式在js中的实现有两种方式。一,对象字面量。二,闭包。

    //
    //        方式一:使用对象字面量形式的单体
    //在js中没有类的概念。js是通过对象实例化对象的。
    //因此,你可以把Singleton看作是一个类,并且实现了一个唯一的对象。(可能有点绕)
    //此外,我们可以通过Singleton.name,Singleton.getName等点操作符来实现对实例的访问。
    //        对象字面量创建的单体的应用。                        ————封装
    //                                  封装————命名空间的使用
    //通过将数据和方法都封装在一个对象内部
    //这样就保护了外部的同名变量不会被意外重写。当本地代码作为第三方js库使用时也不会影响对方的本地代码的变量。————命名空间的作用

    //      假设这是加载第三方js库内定义的变量
            var name='Elvis';
    //        本地js代码
            var Singleton={
                name:'Byronvis',
                getName:function(){
                    alert( this.name);//有时候会出错
                    alert(Singleton.name);//最好使用这种方式
                }
            };
            Singleton.getName();

    //        不使用单体模式的情况下很容易意外重写变量

    //      假设这是加载第三方js库内定义的变量
            var name="Elvis";
    //        本地js代码
            var name='Byronvis';//意外重写了第三方js库的对象
            var getName=function(){
                alert(name);
            };
            getName();

    //                                  封装————代码包装器
    //在拥有许多网页的网站中,有些js代码是所有网页都需要的,它们通常都放在独立的文件中,
    //而有些代码是某个网页专用的,不会被用到其他地方。最好把这两种代码分别包装在自己的单体中。
    //换句话说,就是可以把几个不常用的功能块封装在一个单体中。

    //        方式二:通过闭包创建单体。
    //之前通过对象字面量创建的单体有一些缺点。就是单体对象的数据和方法都是公有的,没有私有属性。

    //通过闭包就可以实现对象的私有属性。
            SecondSingleton=(function(){
    //            对象的私有数据
                var name='Elvis';
    //            对象的私有方法
                function setName(){
                    name='Byron'
                }
                return {
    //                对象的公有数据
                    location:'Hangzhou',
    //                对象的特权方法
                    getLocation:function(){
                        alert(this.location);
                    },
                    getName:function(){
                        alert(name);
                    }
                };
            })();
            SecondSingleton.getName();


    //      闭包方式创建单体的应用。                            ————分支
    //分支的作用:
    //浏览器之间是有差异的。针对于某个功能,不同的浏览器有不同的实现方式
    //我们把每个浏览器的实现方式进行封装,并在页面加载js文件时,通过能力测试或者浏览器嗅探来动态决定使用哪种方式实现该功能。

      _SecondSingleton=(function(){
                var objA={
                    age:22,
                    getAge:function(){
                        alert('age:'+this.age);
                    }
    
                };
                var objB={
                    age:23,
                    getAge:function(){
                        alert(this.age);
                    }
                };
    //            约束条件,实现分支的根本
                return (2>1)?objA:objB;
            })();
            _SecondSingleton.getAge();

     
    //        惰性实例化单体
    //之前两种方式创建的单体,都有一个共同点,当网页加载好js文件后会立即实例化单体。
    // (源于对象字面量方式直接在全局环境中定义,闭包方式的函数也是定义后立即执行)
    //对于单体实例比较大的单体,我们有时候希望其在使用时实例化,不希望过早实例化占用资源。
    //这时候就需要惰性实例化单体了。
    //        惰性实例化单体的思路:将构造器函数封装起来,通过一个外部接口函数延迟返回构造器
    //将实例的构造器这个闭包外层再包围一个闭包。
    //通过外层闭包的特权方法实现对构造器的控制。
    //此时访问单体的属性方法就发生了改变。
    //由此也可以看出惰性实例化单体的主要缺点就是复杂。不如前两种来的直观些。

     ThirdSingleton=(function() {
    //          用于保存实例的私有变量
                var instance;
                return{
    //                调用实例化方法(通过这个方法实现对实例化单体的时间控制)
                    getInstance:function(){
    //                    若实例不存在则实例化对象
                        if(!instance){
                            instance=Constructor();
                        }
    //                    若实例存在则返回实例
                        return instance;
                    }
    
                };
                //单体实例的构造器
                function Constructor() {
    //                对象的私有数据
                    var name = 'Elvis';
    //                对象的私有方法
                    function setName() {
                        name = 'Byron'
                    }
    
                    return {
    //                对象的公有数据
                        location: 'Hangzhou',
    //                对象的特权方法
                        getLocation: function () {
                            alert(this.location);
                        },
                        getName: function () {
                            alert(name);
                        }
                    }
                }
            })();
    //      访问单体的属性的方法改变,必须有getInstance()前缀
            ThirdSingleton.getInstance().getLocation();

     

      </script>
    </head>
    <body>
    这真的只是一个测试文档啊。
    </body>
    </html>

  • 相关阅读:
    TabControl添加关闭按钮
    C# 遍历窗体上控件方法
    个人JS脚本验证大全[转]
    c# 窗体位置任意调
    Sql存储过程解密算法 破解微软的加密算法
    网页居中
    兼容IE和Firefox的设为首页和收藏的Javascript代码
    定义类成员
    HikariCP
    post请求重定向到get请求问题
  • 原文地址:https://www.cnblogs.com/byronvis/p/4168177.html
Copyright © 2011-2022 走看看