您如何向知道其所包含概念的人(例如函数,变量等)解释JavaScript闭包,但不了解闭包本身?
我已经看过维基百科上给出的Scheme示例,但遗憾的是它并没有帮助.
之前的一张海报在Javascript中询问了Function.bind vs Closure:如何选择?
并且部分收到了这个答案,这似乎表明bind应该比闭包更快:
范围遍历意味着,当您要获取存在于不同范围内的值(变量,对象)时,会增加额外开销(代码执行速度变慢).
使用bind,您将调用具有现有范围的函数,因此不会进行范围遍历.
两个jsperfs表明bind实际上比闭包慢得多.
这是作为对上述评论发布的
并且,我决定编写自己的jsperf
那么为什么绑定这么慢(铬+ 70%)?
由于它不是更快并且闭包可以起到相同的作用,应该避免绑定吗?
我使用jQuery创建了一个'control',并使用jQuery.extend来帮助尽可能地将其作为OO.
在我的控件初始化期间,我连接各种点击事件,如此
jQuery('#available input',
this.controlDiv).bind('click', this, this.availableCategoryClick);
Run Code Online (Sandbox Code Playgroud)
请注意,我将'this'作为bind方法中的data参数.我这样做是为了让我可以获取附加到控件实例的数据而不是触发click事件的元素.
这很好用,但我怀疑有更好的方法
在过去使用过Prototype之后,我记得一个绑定语法,它允许你控制事件中'this'的值.
什么是jQuery方式?
解决了
关于这个问题,网上有很多矛盾的信息.感谢@John,我设法解决了闭包(如下所示)不是内存泄漏的原因,即使在IE8中 - 它们并不像人们所说的那样普遍.事实上,我的代码中只发生了一次泄漏,事实证明并不难解决.
从现在开始,我对这个问题的回答是:
AFAIK是唯一一次IE8泄漏的时候,就是在全局对象上设置了事件/处理程序.(window.onload,window.onbeforeunload,...).要解决这个问题,请参阅下面的答案.
巨大的更新:
我现在已经完全迷失了......经过一段时间深入挖掘新旧文章,我至少留下了一个巨大的矛盾.尽管之一的 JavaScript的大师的(道格拉斯·克罗克福德)说:
由于IE无法完成其工作并重新开始循环,因此我们不得不这样做.如果我们明确地打破循环,那么IE将能够回收内存.根据微软的说法,闭包是造成内存泄漏的原因.这当然是非常错误的,但它导致微软向程序员提供了关于如何应对微软错误的非常糟糕的建议.事实证明,很容易打破DOM端的循环.几乎不可能在JScript端打破它们.
正如@freakish所指出的,我的下面的代码段与jQuery的内部工作类似,我觉得我的解决方案不会导致内存泄漏.与此同时,我找到了这个MSDN页面,该部分Circular References with Closures对我特别感兴趣.下图几乎是我的代码如何工作的示意图,不是它:

唯一的区别是我的常识是不将我的事件监听器附加到元素本身.
所有相同的Douggie都是非常明确的:闭包不是IE中mem泄漏的根源.这个矛盾使我无法理解谁是对的.
我也发现泄漏问题在IE9中也没有完全解决(找不到链接ATM).
最后一件事:我还得知IE管理JScript引擎之外的DOM,当我<select>根据ajax请求更改元素的子元素时,这让我感到烦恼:
function changeSeason(e)
{
var xhr,sendVal,targetID;
e = e || window.event;//(IE...
targetID = this.id.replace(/commonSourceFragment/,'commonTargetFragment');//fooHomeSelect -> barHomeSelect
sendVal = this.options[this.selectedIndex].innerHTML.trim().substring(0,1);
xhr = prepareAjax(false,(function(t)
{
return function()
{
reusableCallback.apply(this,[t]);
}
})(document.getElementById(targetID)),'/index/ajax');
xhr({data:{newSelect:sendVal}});
}
function reusableCallback(elem)
{
if (this.readyState === 4 && this.status === 200)
{
var data = JSON.parse(this.responseText);
elem.innerHTML …Run Code Online (Sandbox Code Playgroud) 我来自Prototype JS背景,其中通过使用来鼓励OO Javascript Class.create().现在我正在做一些JQuery工作,我正在尝试编写一些结构合理的JQuery代码,例如,我可以从两个不同的单击事件处理程序调用相同的对象函数.
这是Prototype中的代码:
document.observe("dom:loaded", function() {
// create document
APP.pageHelper = new APP.PageHelper();
});
// namespace our code
window.APP = {};
// my class
APP.PageHelper = Class.create({
// automatically called
initialize: function(name, sound) {
this.myValue = "Foo";
// attach event handlers, binding to 'this' object
$("myButton").observe("click", this.displayMessage.bind(this))
},
displayMessage: function() {
console.log("My value: " + this.myValue); // 'this' is the object not the clicked button!
}
});
Run Code Online (Sandbox Code Playgroud)
我想知道如何在JQuery中复制以下代码,其中无法将函数调用绑定到它所调用的对象,并且'this'始终是单击的元素.
我听说过道格拉斯·克罗克福德"模块"模式(http://www.yuiblog.com/blog/2007/06/12/module-pattern/)的方法,但我很乐意,如果有人能告诉我如何你将使用JQuery和那个模式实现上面的代码.
提前致谢.
我有这个类,我使用jQuery和Prototype的组合:
var MyClass = Class.create({
initElements: function(sumEl) {
this.sumEl = sumEl;
sumEl.keyup(this.updateSumHandler);
},
updateSumHandler: function(event) {
// Throws error here: "this.updateSum is not a function"
this.updateSum();
},
updateSum: function() {
// does something here
}
});
Run Code Online (Sandbox Code Playgroud)
我怎么能打电话this.updateSum()呢?
javascript ×5
jquery ×3
closures ×2
oop ×2
prototypejs ×2
scope ×2
function ×1
memory-leaks ×1
node.js ×1
performance ×1
this ×1
v8 ×1
variables ×1