为了账号安全,请及时绑定邮箱和手机立即绑定

用JavaScript实现单例的最简单/最干净的方法?

用JavaScript实现单例的最简单/最干净的方法?

BIG阳 2019-06-27 16:10:44
用JavaScript实现单例的最简单/最干净的方法?在JavaScript中实现单例模式的最简单/最干净的方法是什么?
查看完整描述

3 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

我认为最干净的方法是:

var SingletonFactory = (function(){
    function SingletonClass() {
        //do stuff
    }
    var instance;
    return {
        getInstance: function(){
            if (instance == null) {
                instance = new SingletonClass();
                // Hide the constructor so the returned object can't be new'd...
                instance.constructor = null;
            }
            return instance;
        }
   };})();

之后,您可以将函数调用为

var test = SingletonFactory.getInstance();


查看完整回答
反对 回复 2019-06-27
?
慕容3067478

TA贡献1773条经验 获得超3个赞

我不同意将模块模式用作单例模式的替代品。我经常看到在完全没有必要的地方使用和滥用单例,我确信模块模式填补了许多空白,否则程序员就会使用单例,但是模块模式是单身人士。

模块模式:

var foo = (function () {
    "use strict";
    function aPrivateFunction() {}
    return { aPublicFunction: function () {...}, ... };}());

在模块模式中初始化的所有内容都发生在Foo被宣布。此外,模块模式可以用于初始化构造函数,然后可以多次实例化构造函数。虽然模块模式是许多作业的正确工具,但它并不等同于单例。

单例模式:

短形

var Foo = function () {
    "use strict";
    if (Foo._instance) {
        //this allows the constructor to be called multiple times
        //and refer to the same instance. Another option is to
        //throw an error.
        return Foo._instance;
    }
    Foo._instance = this;
    //Foo initialization code};Foo.getInstance = function () {
    "use strict";
    return Foo._instance || new Foo();}

长格式,使用模块模式

var Foo = (function () {
    "use strict";
    var instance; //prevent modification of "instance" variable
    function Singleton() {
        if (instance) {
            return instance;
        }
        instance = this;
        //Singleton initialization code
    }
    //instance accessor
    Singleton.getInstance = function () {
        return instance || new Singleton();
    }
    return Singleton;}());

在我提供的Singleton模式的两个版本中,构造函数本身都可以用作访问器:

var a,
    b;a = new Foo(); //constructor initialization happens hereb = new Foo();console.log(a === b); //true

如果不习惯以这种方式使用构造函数,则可以在if (instance)语句,并坚持使用长表单:

var a,
    b;a = Foo.getInstance(); //constructor initialization happens hereb = Foo.getInstance();console.log(a === b); //true

我还应该指出,单例模式与隐式构造函数模式非常匹配:

function Foo() {
    if (Foo._instance) {
        return Foo._instance;
    }
    //if the function wasn't called as a constructor,
    //call it as a constructor and return the result
    if (!(this instanceof Foo)) {
        return new Foo();
    }
    Foo._instance = this;}var f = new Foo(); //calls Foo as a constructor-or-var f = Foo(); //also calls Foo as a constructor


查看完整回答
反对 回复 2019-06-27
  • 3 回答
  • 0 关注
  • 424 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信