以前在我公司工作过的员工使用以下形式的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;
}
答案 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 。你提供的第一个代码的优点是,只有在第一次调用函数时才会这样做,你可以认为这是一个优点:“不要在可能永远不会使用的东西上浪费时间。”