js单例模式

js实现单例模式

1.最简单的方式

复制代码
let SingleTest=(function () {
    let _instance = null;
    return function () {
        if(_instance==null){
            _instance=this;
        }
        return _instance;
    }
})();

let i1=new SingleTest();
let i2=new SingleTest();
console.log(i1===i2);  结果返回 true
复制代码

2.如果要求加上参数

复制代码
let SingleTest=(function () {
    let _instance = null;
    function _init(ops) {
        for(let i in ops){
            this[i]=ops[i];
        }
    }
    return function (args) {
        if(_instance==null){
            _instance=this;
        }
        _init.call(_instance,args);  如果是一个单纯的函数,调用call方法需要将对象传递进去,这样就相当于,实例方法了
        return _instance;            但是这样做有点不好看,可以使用 原型链将 _init函数变成实例方法
    }
})();

let i1=new SingleTest({name:"escapist1"});
let i2=new SingleTest({name:"escapist3"});
console.log(i1===i2);  结果是true
console.log(i1.name);  结果是escapist3
复制代码

3.改进一下  不使用call方法来

复制代码
let SingleTest=(function () {
    let _instance = null;
    SingleInstance.prototype._init=function (ops) {
        for(let i in ops){
            this[i]=ops[i];
        }
    };
    function SingleInstance(args) {
        if(_instance==null){
            _instance=this;
        }
        _instance._init(args);
        return _instance;
    }
    return SingleInstance;
})();

let i1=new SingleTest({name:"escapist1"});
let i2=new SingleTest({name:"escapist3"});
console.log(i1===i2);  结果是true
console.log(i1.name);  结果是escapist3
复制代码

 4.如果给出的参数没有就用默认值,有就用给出的let SingleTest = (function () {    let _instance = null;

复制代码
let SingleTest = (function () {
let _instance = null;
let _default = {age: 25};
SingleInstance.prototype._init = function (ops) {
for(let j in _default){
this[j]=_default[j];
}
for (let i in ops) {
this[i] = ops[i];
}
};
function SingleInstance(args) {
if (_instance == null) {
_instance = this;
}
_instance._init(args);
return _instance;
}
return SingleInstance;
})();
let i1 = new SingleTest({name: "escapist1"}); 
let i2 = new SingleTest({name: "escapist3"});
console.log(i1 === i2); 结果是 true
console.log(i1.name);  结果是 escapist3
console.log(i1.age); 结果是 25
复制代码

5.还有最后一个问题,有的人不适用new来创建对象,而是使用 let i1=SingleTest() 这样来创建对象 

这种情况下,怎样保证只有一个实let SingleTest = (function () {

复制代码
let SingleTest = (function () {
    let _instance = null;
    let _default = {age: 25};
    SingleInstance.prototype._init = function (ops) {
        for (let a in _default) {
            this[a] = _default[a];
        }
        for (let b in ops) {
            this[b] = ops[b];
        }
    };
    function SingleInstance(args) {
        if (this instanceof SingleInstance) {
            if (_instance == null) {
                _instance = this;
            }
            _instance._init(args);
            return _instance;
        }else {
            if(_instance==null){
                _instance=new SingleInstance;
            }
        _instance._init(args);
return _instance; } } return SingleInstance; })(); let i1 = new SingleTest({name: "escapist1"}); let i2 = new SingleTest({name: "escapist3"}); let i3 = SingleTest({name: "escapist3"}); console.log(i1 === i2); 结果是true console.log(i1 === i3); 结果是true console.log(i1.name); 结果是escapist3 console.log(i1.age); 结果是2
复制代码

至此js完整的单例模式改造完毕

 

posted @   escapist  阅读(2434)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示