我听了Crockford关于JavaScript闭包的演讲,并确信信息隐藏的好处,但我对何时使用回调函数没有确切的理解。
一个人可以在有或没有回调的情况下完成相同的功能,这在很大程度上是正确的。
作为编写代码的人,在决定何时使用回调/闭包时,我应该牢记哪些启发式或提示?
我不是在寻找“闭包使代码更安全”这一笼统的说法,而是在寻找一系列实际的例子或经验法则来说明回调是正确的想法。
克罗克福德的演讲:http://www.yuiblog.com/blog/2010/04/08/video-crockonjs-5/
发布于 2010-04-12 21:50:56
假设您想要一个函数,当您创建新的DOM元素时,可以使用该函数返回一个惟一的"id“值。现在,在类似Java的东西中,您可以创建一个具有内部私有计数器的类,然后拥有一个将计数器附加到某个前缀字符串的方法。好吧,在Javascript中:
var getId = (function() {
var counter = 0;
return function() {
return "prefix" + counter++;
};
})();
现在,变量"getId“被绑定到一个由另一个函数创建的函数,并以这样一种方式创建:它有一个持久变量可在调用之间使用。类似地,如果我想要有一系列"getId“函数(比如,我可能添加的每种DOM元素对应一个函数),我可以这样做:
var getIdFunc = function(prefix) {
var counter = 0;
return function() {
return prefix + counter++;
};
};
var getId = {
'div': getIdFunc('div'),
'span': getIdFunc('span'),
'dl': getIdFunc('dl'),
// ...
};
现在我可以调用getId.div()
为一个新的<div>
获取一个新的"id“值。该函数是通过调用一个函数创建的,该函数提供了隐藏在闭包中的两个值:前缀字符串(作为参数传入)和计数器(在闭包作用域中声明的var
)。
一旦你习惯了它,这个工具是如此灵活和有用,以至于你在搬回一个没有它的环境时会感到痛苦。
哦,如果你尝试一下,这里有一个小贴士可以帮助你远离StackOverflow :这是一个经常出现的问题:
for (var i = 0; i < 10; ++i) {
var id = "foo" + i;
var element = document.getElementById(id);
element.onclick = function() {
alert("hello from element " + i);
};
}
这里有什么问题?这个函数引用的"i“变量就是这个循环运行的作用域中的"i”。您会注意到,该变量在循环中递增(duhh,对吗?)。那么,每个创建并分配为事件处理程序的小函数都将在闭包作用域中共享相同的单个变量"i“。糟了!解决方案是这样做:
for (var i = 0; i < 10; ++i) {
var id = "foo" + i;
var element = document.getElementById(id);
element.onclick = (function(iCopy) {
return function() {
alert("hello from element " + iCopy);
};
})(i);
}
我们将外部的"i“复制到它自己的闭包作用域中,所以现在每个事件处理程序都有自己的闭包作用域!
总而言之:一旦您习惯了利用闭包的技术,它就会一直出现。这不是一张进入无错误编程的新仙境的免费门票;不要误会我的意思。然而,它是一个非常有用和灵活的范例。
https://stackoverflow.com/questions/2622421
复制相似问题