0

this注: これは、JavaScriptの使用に関する一般的な質問ではないことに注意してください。これは、aspect.around の誤動作に関するものです (呼び出しのスコープを設定するためのものですが、そうではありません)。問題は、aspect.around が誤動作するのはなぜですか? この質問では、再現方法を注意深く読み、提供されているフィドルを使用して再現する必要があります。

問題をフィドルに収めるために、アプリを細断する必要がありました。だからここにあります:

http://jsfiddle.net/mercmobily/THtsv/1/

これは検証付きの単純なフォームです。

  • テキスト ボックスに何かを入力します。ウィジェットの検証メソッドが呼び出されます。
  • 次に送信ボタンを押します。検証は失敗し、aspect.around が呼び出されて検証メソッドがラップされます。
  • その時点、もう一度テキスト ボックスに何かを入力してみてください。「this」がウィジェットではなく「window」に設定されているためにバリデーターが失敗するため、エラーが返されます。

そのため、アスペクトが追加されると、バリデーター機能しなくなります。基本的に、「これ」の価値は失われます。今:

  • spect.around()は、新しいバリデーターを正しいスコープで実行することを意図しており(明らかに)、実行に失敗しています

  • バリデータへの呼び出しを次のように変更することで、この問題を「修正」できreturn originalValidator.call(this, value);ます。

  • コードをバックトレースすると、aspect.around() が通常の動作を行っていることがわかります...しかし、何か間違ったことをしているに違いありません

では、質問: dojo.around() が誤動作thisし、渡されたオブジェクトのスコープに設定されないのはなぜですか?

メルク。

4

2 に答える 2

1

あなたが求めていることを正確に理解するのは簡単ではありません。あなたのjsFiddleから、このコメントが表示されるので、ここであなたが提起した質問に答えようとします:

  // QUESTION: FIND OUT WHY WE NEED THIS "call"
  return originalValidator(value);
  // return originalValidator.call(this, value);

.callの値を保持するために hereが必要な理由の答えは、関数呼び出しを行う際の動作thisの一般的な説明で後述するとおりです。this

このステートメントのように通常の関数呼び出しを行うと、次のようになります。

  return originalValidator(value);

の値が にthis戻されwindowます。それがJavaScriptの仕組みです。その関数での現在の値を保持したい場合は、またはまたは呼び出しを使用して setthisの特定の値が必要であることを指定する必要があります。通常の関数呼び出しの値は、関数にバインドされていません。これは呼び出し元によって設定され、呼び出し元が望むものであれば何でもかまいません。指定しない場合、javascript は に設定され、それがまさにコード内で起こっていることです。this.call().apply()obj.method()thisthiswindow


の値がどのようにthis設定されるかの一般的な説明を次に示します。この一般的な説明は、特定のケースに適用されます。

単純なルールはthis、javascript の関数呼び出しごとに の値がリセットされることです。単純な関数呼び出しの場合は、(ブラウザー環境にある)thisグローバル オブジェクトに設定されます。windowしたがって、単純な関数呼び出しは常に に設定さthiswindowます。

のようなメソッド呼び出しを行うとobj.method()、は のwhilethisを指すように設定されます。objmethod()

func.apply(a, b)orを使用すると、 orの最初の引数の値を介して、func.call(a, b)何に設定するかを明示的に制御できます。およびの詳細については、この MDN ドキュメントを参照くださいthis.apply().call().call().apply()

于 2012-08-18T05:29:26.423 に答える
0

this現在のコンテキストです。デフォルトでは、グローバル オブジェクト (またはnull厳密モード) であり、オブジェクト ( ) で関数を呼び出すと、foo.bar()そのオブジェクトに設定されます。関数を使用.call()または.apply()呼び出す場合、その関数に渡された最初の引数に設定されます。

thisこれは、別の関数に入ったときに、それが同じであると想定できないことを意味します-その関数を必要なコンテキストで定義したとしてもthis

最も一般的なアプローチは、内部関数の代わりに追加var self = this;してから使用することです。通常の変数であるため、関数のクロージャにあり、関数内の他の何かにバインドされても影響を受けません。selfthisselfthis

于 2012-08-18T02:39:27.427 に答える