1

以下に示すように、Revealing Module パターンを使用する JavaScript があります。後で呼び出すコールバック関数を受け入れます。そのコールバック関数がクラスで定義された関数を呼び出せるようにしたいのですが、機能していません。

window.MyClass = function() {
  var self = this,

  start = function (callback) {
    callback(self);
  },

  cancel = function() {
    console.log('Cancel invoked');
  };

  return {
    start: start,
    cancel: cancel
  };
};

var myCallbackFunction = function(instance) {
  instance.cancel(); // Error: instance.cancel is not a function
};

var obj = new window.MyClass();
obj.start(myCallbackFunction);

このサンプルを Revealing Prototype パターンに作り直すことができ、期待どおりに機能します。私の質問は、RMP を使用してこれを機能させることができるか、それともこのパターンの単なる制限ですか?

ありがとう、ロジャー

4

2 に答える 2

4
window.MyClass = function() {
  var self = this;

  this.start = function (callback) {
    callback(self);
  };

  this.cancel = function() {
    console.log('Cancel invoked');
  };

  return {
    start: this.start,
    cancel: this.cancel
  };
};

次に、これはインスタンス メソッドであり、戻り値を介して利用できます。

しかし、これほど単純なもの (たとえば、プライベート変数がないもの) の場合は、単純なプロトタイプ (「プロトタイプ パターン」) を使用します。

ところで、このシリーズを読んでいる場合は、これらが実際には標準的な用語ではないことに注意してください。

彼はまた、「JavaScript は C# や Java のようにクラスやオブジェクト指向プログラミングの概念を念頭に置いて設計されていませんが、少し手を加えるだけで同様の結果を得ることができます」と述べています。実際、JavaScript はオブジェクト指向プログラミング用に設計されていますが、プロトタイプ ベースです。これまで見てきたように、代替手段を使用できるほど柔軟でもあります。これらの代替手段は、場合によっては間違いなく優れています。

オブジェクトはバインドされたままであるため、self も必要ありません。

そう:

window.MyClass = function(){};

window.MyClass.prototype = {
    start: function (callback) {
        callback(this);
    },

    cancel: function () {
        console.log('Cancel invoked');
    }
};


var myCallbackFunction = function(instance) {
  instance.cancel();
};

var obj = new window.MyClass();
obj.start(myCallbackFunction);
于 2012-10-11T19:43:05.347 に答える
1

コンストラクターからオブジェクトを返さないでください。これは、奇妙な JS の癖の 1 つです。

のインスタンスを取得していませんMyClass。プレーンなオブジェクトを取得しています。コンストラクターがオブジェクトを返す場合、返されるはずだったインスタンスではなく、そのオブジェクトが返されます。

// good!
function MyClass() {};
new MyClass().constructor // returns: function MyClass() {}
new MyClass().constructor == MyClass // true

// bad!
function MyClass() { return {a:123}; };
new MyClass().constructor // returns: function Object() { [native code] }
new MyClass().constructor == MyClass // false

要するに、古典的なスタイルと明らかにモジュールのスタイルはうまく混ざりません。

あなたの場合、のプロパティに割り当てられたthis関数は、その関数を外部に公開することです。代わりにこれが欲しかったのかもしれません。

window.MyClass = function() {
  var self = this;

  var start = function (callback) {
    callback(self);
  };

  var cancel = function() {
    somePrivateFn();
    console.log('Cancel invoked');
  };

  var somePrivateFn = function() {
    console.log('private function!');
  };

  this.start = start;
  this.cancel = cancel;
};

しかし、プライベートなものが必要ない場合 (あなたの例はすべてを明らかにしているので、プライベートなものは何もありません) Matthew が提案するようなプロトタイプベースのアプローチを使用します。これはあらゆる点でより高速でシンプルです。

于 2012-10-11T19:58:00.160 に答える