質問

これはほぼ機能します:

function myClass(url) {

this.source = url;
this.rq = null;
this.someOtherProperty = "hello";

// open connection to the ajax server
this.start = function() {
    if (window.XMLHttpRequest) {
        this.rq = new XMLHttpRequest();
        if (this.rq.overrideMimeType)
        this.rq.overrideMimeType("text/xml"); 
    } else
        this.rq = new ActiveXObject("Microsoft.XMLHTTP");

    try {
        this.rq.onreadystatechange = connectionEvent;
        this.rq.open("GET", this.source, true);
        this.rq.send(null);
        this.state = 1;
    } catch (err) {
        // some error handler here
    }

}

function connectionEvent() {
    alert("i'm here");
    alert("this doesnt work: " + this.someOtherProperty);
}

} // 私のクラス

つまり、XMLHttpRequest オブジェクトをグローバルに定義するのではなく、クラスのメンバーとして持ち、従来の方法で呼び出すことに他なりません。ただし、connectionEvent コールバック関数内では、関数自体が myClass 内にスコープされているにもかかわらず、「this」の意味が失われます。また、myClass からインスタンス化したオブジェクトが十分な期間存続するようにしました (スクリプト内でグローバルとして宣言されています)。

私が見た JavaScript クラスの使用例では、すべて内部関数内で「this」が使用可能でした。私にとっては、関数を外部に取り出して myClass.prototype.connectionEvent にしたとしても、そうではありません。私は何を間違っているのでしょうか?ありがとう。

役に立ちましたか?

解決

それが機能しない理由は、JavaScript で this 関数がどのように機能するかによって完全に定義されます 呼ばれた, 、定義されている場所ではありません。これは他の言語とは異なります。

持つため this あなたが期待していることを意味するなら、それを「バインド」することによって明示的にそれを保証する必要があります:

this.start = function() {
    var self = this; // Set up something that survives into the closure

    /* ...lots of stuff omitted... */

    this.rq.onreadystatechange = function() {
        // Call `connectionEvent`, setting `self` as `this` within the call
        connnectionEvent.call(self);
    };

詳細については、 this の管理 このブログ投稿, 、しかし基本的には:特に設定をせずに関数を呼び出した場合 this, this 関数内では常にグローバル オブジェクトになります (window, 、ブラウザ上)。設定方法は2通りあります this 電話をかけるとき:

  1. 使用する Function#call (または Function#apply) 上で行ったのと同様に、として使用するオブジェクト参照を渡します。 this 最初のパラメータとして。それは関数を呼び出して設定します this あなたが渡したものすべてに。の違い #call そして #apply これは、関数に渡す追加の引数を指定する方法です。と #call それらを追加の引数として指定します #call 電話をかける(例: func.call(thisArg, arg0, arg1, arg2))、一方、 #apply それらを 2 番目の引数に配列として指定します (func.apply(thisArg, [arg0, arg1, arg2])).
  2. ドット表記を使用すると、次のようになります。関数が割り当てられたプロパティを持つオブジェクトがある場合 ( start プロパティ)、オブジェクト インスタンス、ドット、プロパティ名 (this.start() または foo.start(), 、など)関数を呼び出して設定します this 呼び出し内のオブジェクト インスタンスに送信されます。したがって、ドット表記は 2 つのことを行います 完全に別個の もの:プロパティを検索してその値として関数を見つけ、その関数を次のように呼び出します。 this 通話中にオブジェクトに設定されます。文字通り、それは次のようなものです: var f = obj.func; f.call(obj).

少し話が逸れましたが、次のとおりです。よほどの理由がない限り、私はこの車輪を再発明するつもりはありません。単純に XHR を呼び出すためのライブラリがたくさんあります。 jQuery, プロトタイプ, 閉鎖, 、そして残りのほぼすべて。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top