我认为我错过了关于javascript的非常重要的事情
var gl = 10
$(document).ready(function() {
var obj = {}
obj.test = function() {
gl++
var lc = gl
function y() {
alert('local = ' + lc)
}
(function() {
var k = lc + 1
$('#button').click(function() {
alert('local anonymous = ' + k)
y()
})
})();
}
obj.test()
$('#button').off()
obj.test()
})
在上面的场景中,我定义了一个对象'obj',并为该对象创建了一个方法'test'。在方法内部,我有一个本地函数'y()',由附加到按钮的'click'事件使用。 click事件也附加在匿名函数中。
然后我调用'test()',从按钮取消订阅'click'事件并再次调用'test()'。在结果中,我收到local = 12和local anonymous = 13。
但是我不明白javascript在内存中的作用,特别是在每个步骤上运行'y()'和匿名函数。
我的具体问题如下,但如果您能解释整个流程,我将非常感谢。
所以当我发现引用第一个'obj.test()'的所有事件时。在这种情况下,我猜这只是'点击'事件。 javascript会破坏'obj.test()'范围和所有函数,包括匿名函数范围吗?我需要关心其他事情吗?
我的用例:我正在使用不同的页面行为创建动态页面加载,所以我想在全局对象方法中为每个页面分隔javascript,并且一旦加载了新页面,我想要分离之前的所有事件页面并调用行为函数。但是我突然意识到我并不真正理解javascript是如何工作的,并且这种方法可能存在巨大的内存泄漏。 : - )
非常感谢!
答案 0 :(得分:3)
当您使用.off
取消绑定点击事件时,lc
,k
和y()
可以在此时免费进行垃圾回收(gc) gc运行时的浏览器。在下一行,您调用了obj.test()
,因此此时obj
将无法进行垃圾回收,因为您在取消绑定click事件后再次运行它。 lc
k
和y()
现在再次定义在与第一次调用obj.test时相同的范围内,原始的仍可以自由gc'd,但是新的不是。如果点击事件稍后解除绑定,则lc
,k
,y()
和obj
将不再被任何内容引用,因此gc将免费。< / p>
上面有点混乱,我会尽量让它更清楚。
只要obj
内的某些内容引用范围超出obj.test()
创建范围的内容,obj
就不会被垃圾回收。当一个事件由于调用obj.test()
而绑定时,事件处理程序引用obj.test()
范围内的变量,并且该元素是dom的一部分,因此obj
不能被垃圾收集,直到事件不再绑定到元素。
以下是一个例子:
(function(){
var a = 1;
function doA() {
a++;
}
$("#myEl").click(doA);
})();
只要#myEl
上存在点击事件,就无法对a
和doA
进行垃圾回收。