1

いくつかの複雑な状況を管理するために複数のプロトタイプを使用していますが、'this' の使用に問題があります。正しい用語に慣れていないため、どのように説明すればよいか 100% 確信できるわけではありませんが、やってみます。

関数 X には、関数 Y 内の関数を指す変数があります。関数 Y 内のこのメソッドは、関数 Y のスコープ内にある変数にアクセスしようとしていますが、これを使用すると関数 X を参照します。

プロトタイプなどを使用して、例でJSFiddleを作成しました (それが私がいるシナリオです)。ただし、コードは短いので、以下に含めます。

var Abc = function(options) {
    alert('2');
    options = options || {};
    this.myVar = options.myVar || 'Abc.myVar';
};
Abc.prototype = {
    onEvent: function() {
        alert('myVar: ' + this.myVar);
    }
};
var Xyz = function(options) {
    alert('3');
    options = options || {};
    this.listenFn = options.listenFn || function() {
        alert('x');
    };
    this.myVar = options.myVar || 'Xyz.myVar';
};
Xyz.prototype = {
    execute: function() {
        alert('4');
        this.listenFn();
    }
};
$(document).ready(function(){
    alert('1');
    var a = new Abc();
    var x = new Xyz({listenFn: a.onEvent});

    x.execute();
});

コード実行の順序でアラートを入れました。そう:

  1. ドキュメントの開始準備完了です。
  2. Abc インスタンスの作成です。
  3. Xyz インスタンスの作成です。ここで、Abc のインスタンスの onEvent 関数が Xyz の listenFn に割り当てられます。
  4. Xyz の onEvent を呼び出し、this.myVar の値を表示します。

私が抱えている問題は、Abc のメソッド内で「this」が Xyz インスタンスを参照していることです。Xyz のインスタンスの myVar の値を設定/取得できる必要があります。新しい Xyz ステートメントに渡される関数を作成して、Abc のインスタンスをそれ自体に戻すという厄介なことを行うことができると思いますが、残念ながら、これは私が作業しているものでは不可能です (あまりエレガントではありません)。

乾杯。

4

1 に答える 1

3

編集

これがあなたの質問への答えです

$(document).ready(function(){
    alert('1');
    var a = new Abc();
    var x = new Xyz({listenFn: a.onEvent.bind(a) }); // <------- bind

    x.execute();
});

このように bind を使用するとthis、 a.onEvent 内の値が に事前設定されますa。IE8 はサポートしていませんが、ここからbindシムを簡単に追加できます。

これを行う別の方法は、次のように言うことです。

$(document).ready(function(){
    alert('1');
    var a = new Abc();
    var x = new Xyz({listenFn: function() { a.onEvent() }); 

    x.execute();
});

コードを深く掘り下げることはせずに、次のことだけを述べておきます。JavaScript で の値を理解するのthisは非常に簡単です。それはすべて、関数が呼び出される方法に依存します。

  • がある場合x.foo()、何があっても *は foo の内部thisと等しくなります。x

  • がある場合foo()、何があっても*、thisグローバル オブジェクトになるか、foo 内の厳密なモードでは未定義になります。

  • あなたが言うならnew foo()thisプロトタイプが設定される新しいオブジェクトになりますfoo.prototype

  • と言うとfooの中に*が入ってしまいますがfoo.call(a)、ここではあまり当てはまりません。thisa

*唯一の例外は、foo を次のように宣言した場合です。

var foo = function() { }.bind(obj);

次に、fooのすべての呼び出しに対して事前にバインドthisし、上記のルールをオーバーライドします。obj

于 2012-12-08T06:16:14.993 に答える