再一次,javascript设计模式与开发实践-单例模式

简述

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

有一些对象往往我们只需要一个,那么这种场景适合使用单例模式。

用途

  • 弹窗

案例

假如我们要设计一个弹窗功能,为了节省资源,要求能够复用弹窗节点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var createLayer = (function () {
    var div;

    return function () {
        if(!div) {
            div = document.createElement('div');
            div.innerHTML = '我是浮动窗';
            document.body.appendChild(div);
        }

        return div;
    };
})();

var layer1 = createLayer();
var layer2 = createLayer();

console.log(layer1 === layer2); // true

优化

以上虽然实现一个可用的单例,但假如需求变为新建一个iframe,或者新建一个script标签呢?

复制照抄一遍实在是很low的做法,遵循单一职责原则,我们可以把不变的部分隔离开来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var getSingle = function (fn) {
    var rst;

    return function () {
        return rst || (rst = fn.apply(this, arguments));
    };
};

var createLayer = function () {
    var div = document.createElement('div');

    div.innerHTML = '我是浮动窗';
    document.body.appendChild(div);

    return div;
};

var createIframe = function () {
    var iframe = document.createElement('iframe');

    iframe.src = 'http://g.cn';
    document.body.appendChild(iframe);

    return iframe;
};


var getLayer = getSingle(createLayer);
var layer1 = getLayer();
var layer2 = getLayer();

console.log(layer1 === layer2); // true


var getIframe = getSingle(createIframe);
var iframe1 = getIframe();
var iframe2 = getIframe();

console.log(getIframe === getIframe); // true