木灵鱼儿

木灵鱼儿

阅读:157

最后更新:2022/05/01/ 22:54:19

第六章 设计模式

本章比较水,就写一个js实现的单例模式吧

单例模式

function Test() {
    //有缓存了直接抛出缓存
    if (typeof Test.instance === "object") {
        return Test.instance;
    }

    //其他逻辑代码
    ...

    //缓存并抛出
    Test.instance = this;
    return this;
}

var a = new Test();
var b = new Test();
console.log(a === b);  //true

使用这种方式非常简单,但是会存在一个问题就是instance属性是一个公开属性,它有可能会被修改。

闭包

为了防止instance静态属性被修改,我们可以使用闭包的方式

 function Test() {
     var instance = this;

     //用户逻辑
     ...

     //重写
     Test = function() {
         return instance;
     };
 }

 var a = new Test();
 var b = new Test();
 console.log(a === b);  //true

使用这种方式可以防止instance被修改,但是会有一个新的问题:instance被初始化后就无法在给原型添加新属性了

 function Test() {
     var instance = this;

     //用户逻辑
     // ...

     //重写
     Test = function() {
         return instance;
     };
 }

 //初始化之前可以加属性
 Test.prototype.getName = function() {
     console.log("test");
 };

 var a = new Test();

 //初始化之后就不行了
 Test.prototype.getAge = function() {
     console.log(16);
 };

 var b = new Test();

 console.log(a === b); //true

 a.getName(); //test
 b.getName(); //test

 a.getAge(); // is not a function
 b.getAge(); // is not a function

由于复写了构造函数,除了属性无法添加,constructor指针也不能这么去对比了:

a.constructor === Test; //false

为了能解决这些问题,我们需要再调整一下!

var Test = (function() {
    var instance;

    return function() {
        if (instance) {
            return instance;
        }
        //初始化
        instance = this;

        //用户逻辑
        //...

        // return instance;  隐式return了,可以不写
    };
})();

版权申明

本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。

关于作者

站点职位 博主
获得点赞 13
文章被阅读 157

相关文章

目录树