2011-08-16 9 views
4

は、誰かが説明していただけますか?jQueryの匿名関数の変数のスコープ

を編集してください:問題の原因と思われるqueryTypeプロパティが実際に設定されていません。申し訳ありません。私はまだ誰かのためになぜの仕事をするのかを説明することに興味があります。これは、クリック機能がデータオブジェクトの範囲外で実行されていることを前提としています。

+0

この関数は実際にはここでは呼び出されません。それは周りを渡され、それが呼び出されたときに文脈が異なります。 – QuentinUK

+0

データは未定義かdata.queryTypeは未定義ですか? – Dennis

+0

クリック機能は 'data'と同じコンテキストで定義されているので動作します。クリックイベントが生成されると、このクリック関数が呼び出され、関数が作成されたスコープ内で 'data'が検索されます。 – buryat

答えて

1

data関数が呼び出されますが、それを返すときも(それゆえ、あなたのコールバックが呼び出される前に)いない場合のみです。呼び出しシーケンスは次のようになります。

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

私はあなたの状況の正確な状況はわかりませんが、何が起こる可能性があるかを要約しています。

dataでクロージャを作成すると、dataにつかんでいますが、これは内部のものをロックしたことを意味しません。datadataがどこから来ている


は、今、私たちは知っていること、それが最初の場所で壊れた理由dataが正しいと放置されたときにそれが動作する理由は、我々は考えることができます。

あなたは匿名のコールバック関数を作成する場合:

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

あなたが(または、より正確に、何data点まで)とdataが殺されることはありませんdataを参照の上保持しているクロージャを作成しているが誰もそれを参照していなくなるまでオフにします。変数の有効期間はスコープによって異なります。あなたのdata変数はあなたのdisplayResults機能の中に生きています。しかし、変数は単にメモリ内のオブジェクトとそのオブジェクトを参照(または指す)するだけで、もはやそれが誰も参照しなくなるまで多かれ少なかれ固執します。

変数名と名前付きオブジェクトは、別々の存続期間を持つ別個のエンティティです。ブルース・リーを引用するには

天国の栄光をすべて忘れてしまいます。

ポインタと呼ばれていない場合でも、プログラミングの際にポインタから離れてしまうことはありません。

+0

ありがとうございます。データオブジェクトは正しく(私の悪い)。編集を参照してください - あなたは何が起こっているのか説明できますか? – Flash

+0

@Flash:物事をはっきりさせるかもしれない(またはしないかもしれない)アップデートを加えました。 –

+0

ありがとう、それは助けになりました。 1つの質問:新しい 'data'でdisplayResultsを呼び出し続けると、このようなクロージャがメモリリークを引き起こすのでしょうか?古い匿名関数と関連する古いデータがクリーンアップされると確信できますか? – Flash

0

スコープに関係なく変数の割り当てを追跡するには、getterとsetterを使用する必要があります。 displayResultsコントロールを呼び出す

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; 
}