我最近一直在进入OOP javascript,越来越多的我听说过闭包。经过一天扭曲我的大脑后,我现在明白了它们*但我仍然没有看到使用物体的优势。他们似乎做了同样的事情,但我怀疑我错过了什么。
*我认为
修改
我花了20分钟尝试使用写为对象的计数器和写为闭包的计数器来编写示例。我得出结论,我仍然不理解闭包。
第二次修改
好的,我已经设法鞭打一个极其简单的例子。这两者之间并不多,但我发现对象版本更具可读性。为什么我会选择一个而不是另一个?
/*** Closure way ***/
function closureCounter() {
var count = 0;
return {
increase : function() {
count++;
alert(count);
},
decrease : function () {
count--;
alert(count);
}
};
}
var myCounter = closureCounter();
myCounter.increase();
myCounter.decrease();
/*** Object way ***/
function objCounter() {
var count = 0;
this.increase = function() {
count++;
alert(count);
}
this.decrease = function() {
count--;
alert(count);
}
}
var myCounter = new objCounter();
myCounter.increase();
myCounter.decrease();
答案 0 :(得分:3)
当一个闭包用更干净,更简单的代码做同样的事情时,你不必冒着额外的错误和混乱来创建一个全新的对象。使用闭包,链接对象要容易得多。
案例:
function attachOnclick(eSource, eParent) {
var e = document.createElement("div");
eParent.appendChild(e);
eSource.onclick = function() { e.style.backgroundColor = "881010"; }
}
与
var elemLinks = [];
function attachOnclick2(eSource, eParent) {
var e = document.createElement("div");
eParent.appendChild(e);
elemLinks.push({elemSrc: eSource, elemDest: e}); // Append to mappings list
eSource.onclick = changeColor;
}
function changeColor() {
for(var i = elemLinks.length; i--;) {
if(this == elemLinks[i].elemSrc) { // We've found our match
elemLinks[i].elemDest.style.backgroundColor = "881010";
return true;
}
}
return false;
}
如果您在第二个示例中发现任何错误,那么它只是证明了我的观点,即闭包使编写更简单,更清晰的代码更容易。
答案 1 :(得分:3)
像masterik说的那样,你在比较苹果和橘子。
对象只是键/值对的集合。关闭与变量范围有关。您可以通过将代码的这一部分包装在函数中来在任何场景中创建闭包。这会在该函数范围内创建一个新的闭包。
http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/
两个对象创建示例之间的区别与JS中编写类/对象的不同模式有关。我相信的第一个例子叫做模块模式?第二个例子是在JS中定义类的另一种常见方法,或者你也可以使用对象的原型来添加这些方法。
有关如何编写类的更多信息,请尝试使用Google搜索“js类模式”(有相当多的资源,具有不同的模式 - 模块,显示模块,单例等)