zoukankan      html  css  js  c++  java
  • js单例模式

    js实现单例模式,经常使用两种方法,一种是使用构造函数的静态属性中缓存该实例,另一种是将实例包装在闭包中。

    第一种实现方式:

    //静态属性中单例模式
    function Universe() {
        if (typeof Universe.instance === "object") {
            return Universe.instance;
        }
        //正常运行
        this.start_time = 0;
        this.bang = "Big";
    
        //缓存
        Universe.instance = this;
        //隐式返回
        //return this;
    }
    
    var uni = new Universe();
    var uni2 = new Universe();
    console.log(uni === uni2 );  //true

    第二种实现方式:

    /闭包中实现单例模式
    function Universe(){
        //缓存实例
        var instance = this;
        //正常进行
        this.start_time = 0;
        this.bang = "Big";
        //重写该构造函数
        Universe = function(){
            return instance;
        }
        //隐式返回
        //return this;
    }
    var uni = new Universe();
    var uni2 = new Universe();
    console.log(uni == uni2);  //true

    上面实现单例模式有个缺点,就是重写构造函数,会丢失所有在初始化和重定义时刻之间添加到它里面的属性,如下

    //test
    Universe.prototype.nothing = true;
    var uni = new Universe();
    //在创建初始化对象之后,再次向该原型添加属性 Universe.prototype.something = true; var uni2 = new Universe(); console.log(uni.nothing); //true console.log(uni2.nothing); //true console.log(uni2.something); //undefined console.log(uni2.something); //undefined console.log(uni.constructor.name); //Universe console.log(uni.constructor === Universe); //false

    其中uni.constructor仍然指向了原始的构造函数。

    如果需要使原型和构造函数指针按照预期的那样运行,可以向下面一样改写代码

    //如果需要使原型和构造函数指针能够按照预期那样运行,改写如下
    function Universe() {
        //缓存实例
        var instance;
        //重写构造函数
        Universe = function Universe() {
            return instance;
        };
        //保留原型属性
        Universe.prototype = this;
        //实例
        instance = new Universe();
    
        //重置构造函数指针
        instance.constructor = Universe;
        //功能实现
        instance.start_time = 0;
        instance.bang = "Big";
    
        return instance;
    }
    //test
    Universe.prototype.nothing = true;
    var uni = new Universe();
    //在创建初始化对象之后,再次向该原型添加属性
    Universe.prototype.something = true;
    var uni2 = new Universe();
    
    console.log(uni.nothing);      //true
    console.log(uni2.nothing);     //true
    console.log(uni2.something);   //true
    console.log(uni2.something);   //true
    console.log(uni.constructor.name);         //Universe
    console.log(uni.constructor === Universe); //true

    另一种解决方案是将构造函数和实例包装在即使函数中。

    var Universe;
    (function(){
        var instance;
        Universe = function Universe(){
            if(instance){
                return instance;
            }
            instance = this;
    
            //所有的功能
            this.start_time = 0;
            this.bang = "BIg";
        }
    }());
  • 相关阅读:
    C# winform 打包成安装程序(exe)
    gitHub----【Mac】sourcetree连接github,报错:fatal:Authentication failed for'https://git…。或提示password required 解决方案
    python3-----往一个字符串中循环添加数据
    python3.8----从多层嵌套Json中解析所需要的值
    记录一些工作知识
    【转】彻底搞懂 async & defer
    【转】判断JS数据类型的四种方法
    动态表单设计
    封装,继承,多态
    语义化版本
  • 原文地址:https://www.cnblogs.com/scnuwangjie/p/5004988.html
Copyright © 2011-2022 走看看