在JavaScript中使用IIFE实现Singleton模式

时间:2017-01-05 18:41:59

标签: javascript

以前在我公司工作过的员工使用以下形式的Singleton模式在JavaScript中创建和获取UI组件:

getDetailForm: function() {
    this.getDetailForm = (function() {
        var form = // form creation logic

        return function() {
            return form;
        };
    }());

    return this.getDetailForm();
}

有没有理由以下列标准方式使用该变体?

getDetailForm: function() {
    var form;

    if (!form) {
        form = // form creation logic
    }

    return form;
}

1 个答案:

答案 0 :(得分:1)

第二个代码块将不记住变量 form 的值:每次调用函数 getDetailForm 时,它代表一个新的闭包和一个新的变量< em> form 是在该范围内创建的,每次都以undefined开头。

了解以下内容如何在每次通话时打印“init”

var o = {
    getDetailForm: function() {
        var form;
        if (!form) {
            form = 'form'; // form creation logic
            console.log('init');
        }
        return form;
    }
}

console.log(o.getDetailForm());
console.log(o.getDetailForm());

你可以通过在单例对象的范围内声明 form 来使它工作,为此你可以使用构造函数来实例化那个对象,同时它是你的<的一个闭包。 em> form 变量:

var o = new function () {
    var form;
    this.getDetailForm = function() {
        if (!form) {
            form = 'form'; // form creation logic
            console.log('init');
        }
        return form;
    }
};

console.log(o.getDetailForm());
console.log(o.getDetailForm());

查看输出现在仅显示“init”一次。

差异

您提供的第一个版本有一个小优势:在第一次调用后,该函数将被一个非常基本的函数替换:

function() {
    return form;
};

该功能中甚至没有if。它只是return。有人可能会争辩说因此它是首选的:在对此函数的任何后续调用中评估if条件时不会丢失性能,当您多次调用该方法时,总是返回相同的结果,除了第一次。

但是,如果要在构造函数中直接将值分配给 form ,也可以使用构造函数模式实现。然后你不再需要方法中的if,因为初始化已经在构造函数中进行了。

请注意,这并不完全相同,因为现在构造函数正忙着将(可能非常耗时的)表达式分配给 form 。你提供的第一个代码的优点是,只有在第一次调用函数时才会这样做,你可以认为这是一个优点:“不要在可能永远不会使用的东西上浪费时间。”