,我去的經驗法則:
對於JavaScript閉包被創建,必須有嵌套功能和內在功能必須能夠訪問或refered由(讓我們只說「觸摸」簡稱)外部函數中的變量。如果找不到這兩個標準中的任何一個,那麼JavaScript中就沒有關閉。
當外部函數中的這種變量(在上面的段落中提到)碰巧是一個DOM元素時,會發生內存泄漏。
在Mozilla文章,讓我們訪問的第一個例子:
function addHandler() {
var el = document.getElementById('el');
el.onclick = function() {
this.style.backgroundColor = 'red';
};
}
顯然,嵌套在另一個函數內的一個功能,並且內功能被分配給一個變量的屬性(EL)在外部範圍內,所以創建了一個閉包。這個變量el也恰好是一個DOM元素,因此存在內存泄漏,正如文章中所解釋的那樣。
在您發佈第二個例子中,
function addHandler() {
var clickHandler = function() {
this.style.backgroundColor = 'red';
};
(function() {
var el = document.getElementById('el');
el.onclick = clickHandler;
})();
}
有外功能,並且嵌套在這個外函數內部是2嵌套(內)的功能,但它們是在同一水平,這意味着一個不是嵌套在另一個裏面。第二個嵌套函數還可以訪問外部函數中的局部變量(clickHandler),因此會創建一個閉包。但是,沒有內存泄漏,因爲外部函數中的此局部變量(clickHandler)不是DOM元素。局部變量el不會導致內存泄漏,因爲它在第二個嵌套函數中是本地的,並且未在外部函數addHandler()中定義。換句話說,它在第二個嵌套函數中是局部的,它不能被第一個嵌套函數訪問,因此沒有內存泄漏的機會。
所以在第一個例子中,即使'el'沒有在'clickHandler'中明確引用,'el'仍然存在於'clickHandler'的作用域對象中?意思是,儘管'clickHandler' *可以引用'el','clickHandler'可以訪問帶有或不帶有明確引用的'el'引用?因此,在'clickHandler'的作用域對象的'el'和'el'對象的'clickHandler'之間創建循環引用?我只是想確保''clickHandler'中的'this'語句不會引起對'el'的循環引用,而不是引用該引用的範圍對象。 –
@TriNoensie:不,它與'this'無關。當一個函數被創建時,它也會獲得對該函數創建的「範圍」的引用,即它對所有在其創建的範圍中都可訪問的變量具有*隱式*引用。這在IE中引起了問題。 –