以前在我公司工作的员工使用以下形式的单例模式在 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;
}
最佳答案
第二个代码块不会记住变量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>表单变量:
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
。这只是一个返回
。有人可能会说,因此它是首选:在此函数的任何后续调用中评估 if
条件不会损失任何性能,当您多次调用该方法时,该函数始终返回相同的结果,除了第一次。
但是,如果您直接在构造函数中将值分配给 form,也可以使用构造函数模式来实现。那么您就不再需要方法中的 if
,因为初始化已经在构造函数中进行了。
请注意,这并不完全相同,因为现在构造函数正在执行将(可能非常耗时)表达式分配给form的繁重工作。您提供的第一个代码的优点是,这仅在第一次调用该函数时完成,您可以认为这是一个优点:“不要在可能永远不会使用的事情上浪费时间”。
关于javascript - 在 JavaScript 中使用 IIFE 实现单例模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41492349/