用 Node.js 實現一個 Singleton

用 Node.js 實現一個 Singleton

原文链接:http://xcoder.in/2014/09/30/javascript-singleton/

今天隨便玩了一道 CodeWar 的題

題意大致就是你需要實現一個 Singleton 也就是單件模式的類,讓其下面代碼執行成功:

var obj1 = new Singleton();
var obj2 = new Singleton();
obj1 === obj2; // => true
obj1.test = 1;
obj2.test; // => 1

並且還有很重要的一點就是 Singleton 的對象的 instanceof 也得的確是 Singleton 才行。

開始試驗

我們猜想 new Singleton() 的結果,如果 Singleton 函數也就是這個類的構造函數沒返回值的話,直接會返回 this,有返回值的話,那麼就是等於其返回值了。

我們碼下面的代碼看一下:

var Singleton = function() {
    return { foo: "bar" };
};

console.log(new Singleton());

跑一遍之後我們的確發現了輸出的值就是:

{ foo: "bar" }

小作弊失敗

於是我這麼做:

var foo = {};
var Singleton = function() {
    return foo;
};

結果上面的幾個條件都符合了,不信大家可以自己輸出一遍看看。

但是——

這東西不是一個 Singleton 的實例,它只是一個簡單的 JSON 對象,所以還是無法通過。

死月の正解

答案有很多,CodeWar 上面每個人的解法都不一樣,但是歸根結底本質還是大同小異的。

就是第一次的時候先直接返回 this,並且把 this 放在某個地方。以後每次來這裏創建的時候返回之前存好的 this 即可:

var Singleton = function() {
    if(Singleton.prototype.instance) return Singleton.prototype.instance = this;
// Do some initialize things
// ...

Singleton.prototype.instance = this;
return this;

};

別的寫法

寫法很多,我這裏隨意挑幾個別人的答案吧。

/**
 * By tjwudi
 */
var Singleton = function(){
  return Singleton.ins = Singleton.ins ? Singleton.ins : this;
};
/**
 * By nonowarn
 */
var Singleton = (function () {
  var instance = null;

return function(){ return instance || (instance = this); }; })();


9 回复

用 Node.js 实现一个 Singleton

原文链接

http://xcoder.in/2014/09/30/javascript-singleton/

题目描述

我们需要实现一个 Singleton 类,使得以下代码能够正确运行:

var obj1 = new Singleton();
var obj2 = new Singleton();
console.log(obj1 === obj2); // => true
obj1.test = 1;
console.log(obj2.test); // => 1

并且还需要确保 Singleton 对象的 instanceofSingleton

开始试验

我们假设如果 Singleton 构造函数没有返回值,则会默认返回 this;如果有返回值,则会返回该返回值。

例如:

var Singleton = function() {
    return { foo: "bar" };
};

console.log(new Singleton()); // 输出 { foo: "bar" }

小作弊失败

我们可以尝试这么写:

var foo = {};
var Singleton = function() {
    return foo;
};

上述代码虽然满足了题目条件,但 foo 只是一个简单的 JSON 对象,并不是一个 Singleton 的实例。

死月の正解

为了实现真正的单例模式,我们需要在第一次创建实例时保存实例对象,并在后续创建时返回该实例对象。具体实现如下:

var Singleton = function() {
    if (Singleton.prototype.instance) {
        return Singleton.prototype.instance;
    }

    // 初始化操作
    // ...

    Singleton.prototype.instance = this;
    return this;
};

别的写法

这里有一些其他实现方法:

By tjwudi

var Singleton = function() {
    return Singleton.ins = Singleton.ins ? Singleton.ins : this;
};

By nonowarn

var Singleton = (function () {
    var instance = null;

    return function() {
        return instance || (instance = this);
    };
})();

以上方法都可以实现单例模式,确保每次调用 new Singleton() 返回的是同一个实例对象。


… 0. 0 咦,我怎么好像收到了一个回复,然后又不见了?

别人都是把 instance 放在构造函数上的,为什么你要放在构造函数的 prototype 上? 文中 nonowarn 的答案我觉得最好。

注册codewar刷了几道题

就这个一句话…心中顿时一万个草呢吗呀呀呀… 2014-10-04_20-40-39.jpg

哎呀,这网站,碰到一个题,写了半天… 判断几点共线,function onLine(points){ … } http://www.codewars.com/kata/points-on-a-line/solutions/javascript

function onLine(points) {

// 去重 var _points = []; _points.has = function(search){ return this.reduce(function(ret,p){ return ret || (p[0] === search[0] && p[1] === search[1]) },false) } points.forEach(function§{ if(!_points.has§){ _points.push§ } })

// points 不重复 points = _points if(points.length < 3) return true

// y = kx + b // y1 = kx1 + b // y2 = kx2 + b var x1 = points[0][0] var y1 = points[0][1]

var x2 = points[1][0] var y2 = points[1][1]

var filter;

if(x1 == x2){ filter = function(x,y){ return x === x1; } } else if(y1 == y2){ filter = function(x,y){ return y === y1 } } else{ var k = (y2 - y1)/(x2 - x1) var b = y1 - k * x1

filter = function(x,y){
  return y === k*x + b
}

}

for(var i = 2;i< points.length;i++){ var x = points[i][0] var y = points[i][1] if(!filter(x,y) ) return false }

return true }

前阵子看了设计模式和对象的一些操作,除了有限状态机(严格来说不算设计模式吧)其他的真没联想到实际工作中的应用场景,同事说是写框架时可以用到,但想来想去也只有观察者

这个 tjwudi 貌似是阿里的?

试验失败是因为你返回的只是字面量声明的对象吧,实际上相当于 return new Object(…),被表象迷惑了

为了实现一个 Singleton 模式,在 Node.js 中我们需要确保在整个应用程序中只有一个实例被创建。下面是几种不同的实现方法:

方法一

var Singleton = (function() {
    var instance;

    function createInstance() {
        const obj = new Object("I am the instance");
        return obj;
    }

    return {
        getInstance: function() {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

// 使用示例
const instanceA = Singleton.getInstance();
const instanceB = Singleton.getInstance();

console.log(instanceA === instanceB); // 输出: true

方法二

class SingletonClass {
    constructor() {
        if (!SingletonClass.instance) {
            SingletonClass.instance = this;
        }
        return SingletonClass.instance;
    }
}

const Singleton = new SingletonClass();

// 使用示例
const instanceA = new Singleton();
const instanceB = new Singleton();

console.log(instanceA === instanceB); // 输出: true

解释

  1. 方法一:通过一个闭包来保持实例状态。getInstance 方法在第一次调用时会创建实例,并将其存储在闭包内的变量 instance 中,以后每次调用都返回同一个实例。
  2. 方法二:通过修改构造函数,使构造函数只能返回已存在的实例。

这两种方法都能确保 Singleton 模式的实现,而且实例化后的对象之间比较恒等(即 === 比较为 true)。

回到顶部