XMLHttpRequest を内部的に呼び出して、onreadystatechange を処理する JavaScript クラス
-
26-09-2019 - |
質問
これはほぼ機能します:
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
電話をかけるとき:
- 使用する
Function#call
(またはFunction#apply
) 上で行ったのと同様に、として使用するオブジェクト参照を渡します。this
最初のパラメータとして。それは関数を呼び出して設定しますthis
あなたが渡したものすべてに。の違い#call
そして#apply
これは、関数に渡す追加の引数を指定する方法です。と#call
それらを追加の引数として指定します#call
電話をかける(例:func.call(thisArg, arg0, arg1, arg2)
)、一方、#apply
それらを 2 番目の引数に配列として指定します (func.apply(thisArg, [arg0, arg1, arg2])
). - ドット表記を使用すると、次のようになります。関数が割り当てられたプロパティを持つオブジェクトがある場合 (
start
プロパティ)、オブジェクト インスタンス、ドット、プロパティ名 (this.start()
またはfoo.start()
, 、など)関数を呼び出して設定しますthis
呼び出し内のオブジェクト インスタンスに送信されます。したがって、ドット表記は 2 つのことを行います 完全に別個の もの:プロパティを検索してその値として関数を見つけ、その関数を次のように呼び出します。this
通話中にオブジェクトに設定されます。文字通り、それは次のようなものです:var f = obj.func; f.call(obj)
.
少し話が逸れましたが、次のとおりです。よほどの理由がない限り、私はこの車輪を再発明するつもりはありません。単純に XHR を呼び出すためのライブラリがたくさんあります。 jQuery, プロトタイプ, 閉鎖, 、そして残りのほぼすべて。