JavaScript设计模式—单例模式

1. 单例模式的定义

1.1 ES6单例模式

保证一个类 仅有一个 实例,并提供一个访问它的全局访问点。

class Window {

    static getInstance(name) {
        if (!this.instance) {
            this.instance = new Window();
        }
        return this.instance;
    }
}

var w1 = Window.getInstance();
var w2 = Window.getInstance();
console.log(w1 === w2); // true

1.2 ES5单例模式

let  Window = function() { }
Window.getInstance = (function () {
    let window = null;
    return function () {
        if (!window)
           window=new Window();
        return window;
    }
})();
let window = Window.getInstance();

问题:并不能阻止客户端直接new Window

1.3 透明单例

let Window = (function () {
    let window;
    let Window = function () {
        if (window) {
            return window;
        } else {
            return (window = this);
        }
    }
    return Window;
})();

let window1 = new Window();
let window2 = new Window();

console.log(window1 === window2) //true

问题:违反了单一职责原则。

1.4 单例与构建分离

function Window() { }

let createSingle = (function () {
    let instance;
    return function () {
        if (!instance) {
            instance = new Window();
        }
        return instance;
    }
})();

let window1 = createSingle();
let window2 = createSingle();

console.log(window1 === window2);// true

1.5 通用的惰性单例

function Window() { }

var createSingle = function (Constructor) {
    let instance;
    const singleConstructor = function () {
        if (!instance) {
            instance = new Constructor(...arguments)
        }
        return instance;
    }
    return singleConstructor;
};
let CreateWindow = createSingle(Window);

let window1 = new CreateWindow();
let window2 = new CreateWindow();

console.log(window1 === window2);// true

1.6 命名空间

const MyApp = {};

MyApp.namespace = function (name, fn) {
    const parts = name.split('.'), last = parts.pop();
    let current = MyApp;
    for (const i in parts) {
        if (!current[parts[i]]) {
            current[parts[i]] = {};
            
        }
        current = current[parts[i]];
    }
    current[last] = fn;
};

MyApp.namespace('event', () => console.log('event'));
MyApp.namespace('dom.style', () => console.log('dom.style'));

console.dir(MyApp);
// 上述代码等价于:

/* const MyApp = {
    event: () => console.log('event'),
    dom: {
        style: () => console.log('dom.style')
    }
}; */

2. 场景

2.1 登录浮窗

const createLoginLayer = (function () {
    let div;
    return function () {
        if (!div) {
            div = document.createElement('div');
            div.innerHTML = '我是登录浮窗';
            div.style.display = 'none';
            document.body.appendChild(div);
        }

        return div;
    }
})();
document.getElementById('loginBtn').onclick = function () {
    const loginLayer = createLoginLayer();
    loginLayer.style.display = 'block';
};

2.2 redux

发布订阅、工厂模式、单例模式。

function createStore(reducer) {
    let state;
    let listeners = [];
    function getState() {
        return state;
    }
    function dispatch(action) {
        state = reducer(state, action);
        listeners.forEach(l => l());
    }
    function subscribe(listener) {
        listeners.push(listener);
        return () => {
            listeners = listeners.filter(item => item != listener);
            console.log(listeners);
        }
    }
    dispatch({});
    return {
        getState,
        dispatch,
        subscribe
    }
}

2.3 缓存

let express = require('express');
let fs = require('fs');
let cache = {};
let app = express();
app.get('/user/:id', function (req, res) {
    let id = req.params.id;
    let user = cache[id];
    if (user) {
        res.json(user);
    } else {
        fs.readFile(`./users/${id}.json`, 'utf8', function (err, data) {
            let user = JSON.parse(data);
            cache[id] = user;
            res.json(user);
        });
    }
});

app.get('/user', function (req, res) {
    let user = req.query;
    fs.writeFile(`./users/${user.id}.json`, JSON.stringify(user), (err) => {
        console.log(err);
        res.json({ code: 0, data: '写入成功' });
    });
});
app.listen(3000);
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容