我有100按钮在我的页面(他们每个人都有类='btn')。
我也有一个单个按钮,其中准备所有其他 100个按钮。
<input type='button' onclick='bindTheClickevent()' />
当按下时,-它调用bindTheClickevent()
-(它将点击事件绑定到所有其他100个事件)。
在Script部分我放了:
function bindTheClickevent ()
{
$(".btn").bind('click',function () {
$(this).css('color','red');
});
}
1)在内存中,匿名函数创建了多少实例 ?
2)在内存中,bindTheClickevent()
函数是否会空闲(GC)?-请注意,Bind在 bindTheClickevent
函数中被称为…
3) 当,最终- bindTheClickevent
函数将被GC ?
让我们做一个改变
function bindTheClickevent ()
{
$(".btn").bind('click',function () {
changeColor($(this));
});
}
function changeColor(obj)
{
$(obj).css('color','red');
}
现在-更改后
1)如果我这样做有什么不同吗?
2)在内存中,匿名函数创建了多少实例 ?
3) bindTheClickevent()
函数是否永远是空闲的(GC) ?-请注意,Bind在 bindTheClickevent
函数中被称为…
"1)在内存中,创建了多少个匿名函数的实例?"
哪个匿名函数?
对于内联onclick
,您将获得一个分配给元素onclick
属性的函数,如下所示:
function(event) {
bindTheClickevent();
}
…或者类似,取决于实现。当元素被解引用或函数从onclick
属性解引用时,该函数将被GC释放。
对于jQuery代码:
$(".btn").bind('click',function () {
$(this).css('color','red');
});
…虽然匿名函数是共享的,但您没有看到的是,如果相关元素还没有绑定jQuery处理程序,jQuery将在内部为每个元素创建一个唯一的函数。
内部处理程序是实际绑定到元素的,当元素接收到事件时,调用该处理程序,分析事件,并调用您最初传递的处理程序(如果需要)。
这意味着100个jQuery绑定元素等于101个唯一的函数实例。
为了确保使用jQuery绑定的任何处理程序都被GC,您需要确保始终使用jQuery删除DOM元素。如果不这样做,存储在jQuery.cache
中的所有数据(包括处理程序)都不会被清理,因此它们将始终通过全局jQuery
命名空间被引用。
编辑:
假设有100
元素有btn
类,没有任何jQuery绑定的处理程序,那么这段代码:
$(".btn").bind('click',function () {
$(this).css('color','red');
});
…将创建101
唯一的Function
实例。
为什么是101
?
你的处理函数是从来没有实际绑定到元素。
因此,调用通用内部处理程序时将分析发生的事件,并查看是否有任何处理程序与使用.bind()
匹配该事件类型的给定元素相关联。如果是,则调用传递的处理程序。
现在假设你绑定了另一个处理程序:
$(".btn").bind('mouseenter',function () {
$(this).css('color','blue');
});
…因为我们绑定了相同的元素,它们已经有了必需的内部处理程序,所以不需要再创建另一个。因此,所发生的一切就是您传递的函数在内部被引用,并在需要时由泛型内部处理程序调用。
因此,根据上面的代码片段,现在存在102
唯一的Function
实例。
看起来在这两种情况下只创建了一个函数的实例。似乎对匿名函数的引用被附加为每个元素的事件处理程序。
示例 -使用闭包来显示按钮事件处理程序之间的范围共享。
注意如果涉及到闭包,这会导致有趣的行为,因为所有元素将共享相同的函数(和闭包作用域)。
不,你声明的函数不会被GC,因为它们的全局作用域。
另外要独立附加它们(而不是通过引用),使用.each()
遍历所选元素并单独附加函数。
$('.btn').each(function() {
$(this).bind('click',function() {
// each '.btn' has it's own copy of
// this anonymous function
}
});
如果您这样做:
for (someiterations)
{
$(myobj).bind("click",function()
{
// ...bla...
});
}
在这种情况下,每次迭代都创建一个新函数。在你的函数中,这不会发生,因为你将函数传递给一个参数,所以有一个地方存储了它的引用(是的,函数参数),它会做这样的事情:
for (iterations)
{
myob.addEventHandler(event, funcref);
}
现在应该没问题了:
- 不这么认为,但是不确定语法。
- 不,因为它在全局作用域中,没有分配给实例,你可以把它看作常量,而不是变量
注意:匿名函数不会被释放,它被事件处理程序引用。