9

オブジェクトに次のプロパティメソッドがあるとします。

  onReady: function FlashUpload_onReady()
  {
     Alfresco.util.Ajax.jsonGet({
       url: Alfresco.constants.PROXY_URI + "org/app/classification",
       successCallback: {
         fn: function (o) {
           var classButtonMenu = [],
               menuLabel, that = this;

           var selectButtonClick = function (p_sType, p_aArgs, p_oItem) {
               var sText = p_oItem.cfg.getProperty("text");
               that.classificationSelectButton.set("label", sText);
           };

           for (var i in o.json.items) {
             classButtonMenu.push({
               text: o.json.items[i].classification,
               value: o.json.items[i].filename,
               onClick: {fn: selectButtonClick}
             });
           }

           this.classificationSelectButton = new YAHOO.widget.Button({
             id: this.id + "-appClassification",
             type: "menu",
             label: classButtonMenu[0].text,
             name: "appClassification",
             menu: classButtonMenu,
             container: this.id + "-appClassificationSection-div"
           });
         },
         scope: this
       },
       failureMessage: "Failed to retrieve classifications!"
     });

アクセスするためではなく、selectButtonClick参照する必要のある関数でそれを理解するのに少し推測作業が必要でしたが(そうでない場合は表示されます)、なぜ使用できないのかわかりません。私の推測では、コンストラクター関数が呼び出されると、オブジェクト全体のプロパティが何らかの形で参照されると、スコープが失われます。thatthisthis.classificationSelectButtonundefinedthisnew YAHOO.widget.Button

誰かが、単に `this.classificationSelectButton'を呼び出すのではなく、参照classificationSelectButtonする必要がある理由を説明してもらえますか?var that = this

4

6 に答える 6

74

理解しておくべき最も重要なことは、関数オブジェクトには固定がないthisということです。つまり、関数の呼び出し方法に応じて値がthis変化します。関数は特定の値で呼び出されるとthis言います。this値は定義時ではなく、呼び出し時に決定されます。

  • 関数が「生の」関数として呼び出された場合(たとえば、do someFunc())はthis、グローバルオブジェクトになります(windowブラウザー内)(またはundefined関数が厳密モードで実行されている場合)。
  • オブジェクトのメソッドとして呼び出された場合はthis、呼び出し元のオブジェクトになります。
  • またはを使用して関数を呼び出すと、callまたはapplythisの最初の引数としてが指定されcallますapply
  • イベントリスナーとして呼び出された場合(ここにあるように)、thisイベントのターゲットとなる要素になります。
  • でコンストラクターとして呼び出された場合、プロトタイプがコンストラクnewター関数のプロパティにthis設定された、新しく作成されたオブジェクトになります。prototype
  • 関数が操作の結果である場合、関数はbind常に、それを生成した呼び出しthisの最初の引数に設定されます。(これは、「関数には固定されていない」ルールbindの唯一の例外です。実際に生成された関数には不変があります。)thisbindthis

使用は、関数の定義時に値var that = this;を格納する方法です(関数の実行時間ではなく、関数の呼び出し方法に応じて、いつでも可能です)。ここでの解決策は、新しく定義された関数が外部スコープで定義された変数にアクセスできるため、新しく定義された関数のスコープに含まれる変数(従来はorと呼ばれていました)にの外部値を格納することです。thisthisthisthatself

于 2012-09-11T13:42:18.397 に答える
5

this実行されるコンテキストに基づいて値が変更されるためです。

selectButtonClick関数内thisでは、外部コンテキストではなく、その関数のコンテキストを参照します。thisしたがって、関数内で参照できる外部コンテキストで別の名前を付ける必要がありselectButtonClickます。

于 2012-09-11T13:32:55.080 に答える
3

字句スコープがあります。関数で宣言された変数と関数に渡された引数は、関数内(およびその内部関数)でのみ表示されます。

var x = 1; // `1` is now known as `x`
var that = this; // the current meaning of `this` is captured in `that`

字句スコープのルールは非常に直感的です。変数を明示的に割り当てます。

次に、動的スコープがありますthis。関数の呼び出し方によって意味が変わる魔法のようなものです。コンテキストとも呼ばれます。それに意味を割り当てるにはいくつかの方法があります。

関数について考えてみましょう。

function print() { console.log(this); }

まず、デフォルトのコンテキストはundefined厳密モードで、グローバルオブジェクトは通常モードです。

print(); // Window

次に、これをメソッドにして、オブジェクトへの参照、ドット、関数への参照を指定して呼び出すことができます。

var obj = {};
obj.printMethod = print;
obj.printMethod(); // Object

ドットなしでメソッドを呼び出すと、コンテキストはデフォルトのコンテキストにフォールバックすることに注意してください。

var printMethod = obj.printMethod;
printMethod(); // Window

最後callに、 /applyまたはbind:のいずれかを使用してコンテキストを割り当てる方法があります。

print.call(obj, 1, 2); // Object
print.apply(obj, [ 1, 2 ]); // Object

var boundPrint = print.bind(obj);
boundPrint(); // Object

コンテキストをよりよく理解するために、このような単純な例を試してみることをお勧めします。John Resigには、JavaScriptのコンテキストに関する非常に優れたインタラクティブなスライドがあり、自分で学習してテストすることができます。

于 2012-09-11T13:47:41.593 に答える
1

this変数に格納すると、他の何かを参照している可能性のある他のスコープでアクセスできます。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this、http://www.quirksmode.org/js/this.htmlおよびJavaScriptの変数のスコープを参照してください。 キーワードの詳細については。this

于 2012-09-11T13:34:09.437 に答える
1

クラスのthisメソッドがDOMイベントから呼び出された場合、参照は機能しません。たとえば、オブジェクトのメソッドがonclickのイベントハンドラーとして使用される場合、thisポインターはイベントが発生したDOMノードを指します。したがって、オブジェクト内にのプライベートバックアップを作成する必要がthisあります。

于 2012-09-11T13:36:11.100 に答える
1

これはjavascriptのキーワードであり、すべての関数内で定義されるデフォルト変数ではありません。したがって、Garethが述べたように、これは関数が呼び出されるコンテキスト、またはコンテキストがない場合はグローバルオブジェクトを参照します。

于 2012-09-11T13:44:33.967 に答える