ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript コールバック関数の変数スコープに関するディスカッション_JavaScript スキル

JavaScript コールバック関数の変数スコープに関するディスカッション_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 18:46:591421ブラウズ

1. 背景
Javascript のコールバック関数については誰もがよく知っていると思います。最もわかりやすい例は、Ajax リクエストを行うときに提供されるコールバック関数です。
実際には、DOM ノードのイベント処理メソッド (onclick、 ondblclick など)これもコールバック関数です。
DWR を使用する場合、コールバック関数は次のように最初または最後のパラメータとして指定できます:
JScript code function callBack(result){ } myDwrService.doSomething(param1,param2,callBack);//DWR 推奨method //or myDwrService.doSomething(callBack,param1,param2);

2. 問題の説明
最近 Dojo Dwr を使用しているときに、次の問題が発生しました。
コールバック関数が A メソッドに属している場合オブジェクト (obj1 として記録) に対して、DWR がコールバック関数を実行すると、
コンテキストは obj1 ではありません。
この現象は、コールバック関数でアクセスされる obj1 のプロパティが未定義であるということです。
バージョン: Dojo1.3.1 および dwr2
3. 問題をシミュレートするコード
次のテスト コードでこの問題をシミュレートできます:
JScript コード

コードをコピー コードは次のとおりです:




テスト呼び出し



callObjMethod メソッドでは、「メソッド」メソッドをコールバックする 2 つの方法を使用しました。
最初の方法: method("Callback through the default context");
コンテキストを指定しない場合、次のことがわかりました。コールバック関数内 アクセス コンテキストの値はグローバル変数の値です。
これは、このメソッドを実行するためのデフォルトのコンテキストがグローバル コンテキストであることを意味します。
2 番目のメソッド:method.call(obj, "明示的なオブジェクト コンテキスト コールバックを指定する");
メソッド実行のコンテキストとして obj を指定すると、オブジェクト内のコンテキストにアクセスできます。

4. DWR の調査
2006 年に DOJO DWR (1.0) を使用していたときにすでにこの問題に遭遇していたため、その時はあまり下調べをせず、dwr のソース コードを直接変更しました。
私は現在 dwr2 を使用しているので、DWR にこの問題に対処する新しい方法があるかどうかを確認したいと思いました。
dwr.jar 内の Engine.js を取り出し、コールバック (_remoteHandleCallback と _) に関する関連コードを確認します。実行)、
は、コールバックを処理する方法が 1.0 よりも単純であるようで、オブジェクトとメソッドを一緒に渡す方法がないことがわかりました。
5. さらに調査する
今回のプロジェクトでは DWR が広く使用されており、そのような要求に応える必要があると考えているため、すぐにはソース コードを修正しませんでした。 Google で Dojo dwr を検索しても、Dojo にはあまり多くのユーザーがいないのかもしれません。
そこで、「JavaScript コールバック オブジェクト コンテキスト」を検索し、特に Java コールバック関数の問題を紹介する記事を見つけました。
http://bitstructs.com/2007/11/javascript-method-callbacks
最も重要なこと 文:
関数がオブジェクト (obj.alertVal()) のメソッドとして呼び出される場合、
「this」は呼び出されたオブジェクト (obj) にバインドされます。 >そして、オブジェクト (func()) なしで関数が呼び出される場合、
「this」は JavaScript グローバル オブジェクト (Web ブラウザーのウィンドウ) にバインドされます。
この記事では、次のような解決策も提供します。クロージャと匿名メソッド
JavaScript では、関数内に関数を作成すると、自動的にクロージャが作成されます。
このクロージャは、対応する関数が作成されたときのコンテキストを記憶できます。
次の場合:
JScript コード var ClosureFunc=function(){ testObj.callback(); }
どこにいても、closureFunc() を直接呼び出すことと testObj.callback() を呼び出すことは同じです。 。
詳細については、上記の記事を参照してください: http://bitstructs.com/2007/11/javascript-method-callbacks。
6. シミュレーション コードを改善します
シミュレーション コードには、次のコールバック メソッドを追加します。
JScript コード






コールテスト



8. 2 つの文要約:
クロージャは関数のローカル変数であり、関数が戻った後も生き続けます。
または
クロージャは、関数が戻ったときに割り当てが解除されないスタックフレームです(あたかも関数が戻ったかのように)。 「スタックフレーム」はスタック上にあるのではなく、malloc されていました!)
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:PNG画像とPNG背景を透明にする方法(マルチブラウザ対応)_JavaScriptスキル次の記事:PNG画像とPNG背景を透明にする方法(マルチブラウザ対応)_JavaScriptスキル

関連記事

続きを見る