3

私は 1 日の大半をモジュール パターンとその 'this' スコープについて読むことに費やしました。最終的に、私は問題の回避策を見つけましたが、より良い方法があると感じています。

実際のコードは 200 行を超えていますが、要約すると次のようになります。objA には、objB がコールバックによって呼び出したいメソッド (publicA) があります。物事を複雑にする詳細は、publicA が仕事をするために publicA_helper からの助けを必要とすることです。( http://jsfiddle.net/qwNb6/2/ )

var objA = function () {
    var privateA = "found";
    return {
        publicA: function () {
            console.log("privateA is " + this.publicA_helper());
        },
        publicA_helper: function () {
            return privateA;
        }
    };
}();

var objB = function () {
    return {
        callback: function (callback) {
            callback();
        }
    }
}();

objA.publicA(); // privateA is found
objB.callback(objA.publicA); // TypeError: Object [object global]

当然のことですが、呼び出し元のコンテキストが「this」の値に影響を与える傾向があることを理解しました。そのため、objA 内に「this」を保持する手段を追加しましたが、どれも機能していないようです。私は var objA = (){}.call({})、設定を試してみましたvar self = this;(それに応じて呼び出しself.publicA_helper()ます)。運がない。

var self;最終的に、パブリック メソッドとともにプライベート変数を追加しました。

init: function() {self = this;},

...そして、objA.init();に渡す前に必ず呼び出すobjA.publicAことobjB.callbackで、実際に機能します。

これを行うためのより良い方法があるという感覚の巨大さを強調することはできません. 私は何が欠けていますか?

4

3 に答える 3

3

一般化されたソリューションは非常に単純です。

モジュールのすべてのメソッドをプライベートとして記述し、パブリックにする必要があるメソッドを公開します。

私はすべてのモジュールをこのように書きます:

var objA = function () {
    var privateA = "found";
    var A = function () {
        console.log("privateA is " + A_helper());
    },
    var A_helper = function () {
        return privateA;
    }
    return {
        publicA: A
        //A_helper need not be exposed
    };
}();

したがって、すべてのメソッドが同じスコープ内にあり、それぞれが同じモジュール内の他のすべてのメソッドに直接アクセスでき、あいまいなthisプレフィックスが回避されます。

objB.callback(objA.publicA);期待どおりに動作するようになりました。

フィドルを見る

于 2013-07-25T11:15:06.560 に答える
0

その理由は、コールバックを呼び出しているときにコンテキストが変更されているためです。一般化されたソリューションではありませんが、コールバックの呼び出し中にコンテキストを指定することでコードが機能することを示しています。

var objA = function () {
  var privateA = "found";
  return {
    publicA: function () {
        console.log("privateA is " + this.publicA_helper());
    },
    publicA_helper: function () {
        return privateA;
    }
  };
}();

var objB = function () {
    return {
        callback: function (callback) {
          callback.call(objA);
        }
   }
}();

objA.publicA(); // privateA is found
objB.callback(objA.publicA); // privateA is found
于 2013-07-25T07:19:46.003 に答える