2011-08-16 82 views
4

是否有人可以解釋爲什麼以下 不起作用 作品:jQuery的匿名函數變量的作用域

function displayResults(data) { 
    $("#odNextPage").click(function() { 
     alert(data.queryType); // "undefined" 
     return false; 
    }); 
} 

爲什麼我使用的數據對象的點擊匿名函數裏面?

編輯:queryType屬性沒有真正設置,我認爲造成了問題,對不起。因爲點擊功能是在數據對象範圍之外執行的,所以我仍然有興趣解釋爲什麼它現在確實工作

+0

這個函數實際上並沒有在這裏調用。它被傳遞,當它被稱爲上下文是不同的。 – QuentinUK

+0

數據是未定義的還是data.queryType未定義? – Dennis

+0

它可以工作,因爲點擊功能是在「數據」相同的上下文中定義的。當產生點擊事件時,它會調用這個點擊函數,並且在創建函數的範圍內查看'data'。 – buryat

回答

1

調用displayResults控制的事情data不僅當函數被調用,而且當它返回時(並因此在你的回調函數被調用)。呼叫順序可能如下所示:

data = { /* interesting things */ }; 
displayResults(data); 
delete data.queryType; 
// Time passes and then your callback gets called 
// but data.queryType is undefined. 

我不知道您的情況的具體情況,但上面總結了可能發生的情況。

當您通過data產生關閉時,您正在抓住data但這並不意味着您已鎖定data中的內容。


現在我們知道data是從哪裏來的,爲什麼它首先被打破,我們可以考慮爲什麼它的工作原理時data是正確的,單獨留在家中。

當您創建匿名回調函數:

function() { 
    alert(data.queryType); 
    return false; 
} 

你創建保存到一個參考data(或者,更準確地說,是什麼data點)和data就不會被撞死一個封閉直到沒有人蔘考它爲止。變量的生命週期取決於其範圍;您的data變量已存在於您的displayResults函數中。但是變量只會引用(或指向)內存中的對象,並且該對象或多或少會一直存在,直到沒有人再引用它爲止。

變量名稱和被命名的對象是具有不同生存期的獨立實體。引用布魯斯李:

不要專注於手指,否則你會錯過所有的天堂榮耀。

即使它們沒有被調用指針,你也不能脫離編程中的指針。

+0

感謝,現在的工作,我已經填補了數據對象正確(我的不好)。請參閱編輯 - 你能解釋發生了什麼嗎? – Flash

+0

@Flash:我添加的更新,其可以(或可以不)澄清的東西。 –

+0

謝謝,這幫助了很多。疑問一:請問像這樣的封閉導致內存泄漏,如果我一直在打新'data' displayResults,或者我可以確信的是,老匿名函數和相關的舊數據將被清理? – Flash

0

您應該使用getters和setter來跟蹤變量賦值,而不管範圍如何。

var data = {}; 
setDataQueryType('post'); 

$("#odNextPage").click(function() { 
    alert(getDataQueryType()); // 'post' 
    setDataQueryType('get'); 
    alert(getDataQueryType()); // 'get' 
    return false; 
}); 

// Getter for query type 
function getDataQueryType() { 
    return data.queryType; 
} 

// Setter for query type 
function setDataQueryType(val) { 
    data.queryType = val; 
} 
相關問題