29

次のことを達成するための最良のデザインパターンは何ですか(これは機能しません)?

var obj = (function() {

  // code defining private variables and methods

  var _obj = {
    property: value,
    method1: function() {
      // do stuff
    },
    method2: function() {
      // use property
      var prop = _obj.property; // obviously doesn't work
      // call method1
      obj.method1(); // "obj" not finished being defined yet!
    }
  };

  // obviously now I could do...
  var prop = _obj.property;

  return _obj;

})();

// and I could now do...
obj.method1();

私がうまくいくと思うバリエーションは

var obj = (function() {

  var property = value,
      method1 = function() {
        // do stuff
      },
      method2 = function() {
        // use property
        var prop = property;
        // call method1
        method1();
      },
      _obj = {
        property: property,
        method1: method1,
        method2: method2
      };

  return _obj;

})();

new同様に、オペレーターで作成することを意図したオブジェクトに対してどのように機能しますか?コンストラクター関数自体の中で、を書くことができますthis.method()。しかし、コンストラクターを小さく保ち、作成時にカスタマイズされる可能性のあるものだけを定義し、残りをプロトタイプで定義したい場合はどうでしょうか。(これは一般的なパターンのようです。)プロトタイプ内のプロパティ/メソッドは何らかの方法で相互作用できますか?

var MyObj = function(name) {
  this.name = name;
};

var obj = new MyObj('Bob');

MyObj.prototype = {
  called_often: function() {
    // lots more code than just the following
    return document.getElementById('someID').value;
  },

  global_default: 'value', // can be changed, so need to pull value when run

  does_stuff: function(value) {
    var str = global_default + value, // can't access global_default on its own
        input = MyObj.called_often(), // doesn't work; MyObj.prototype.called_often() DOES
        name = this.name; // 'this' used in the prototype doesn't work
                          // even within a created object
    return name + input + str;
  }
};

この問題が発生したときはいつでも、結果を達成するためのより良い方法があると確信しています。このコードは状況に固有のものではなく、一般的な問題を示しているだけです。ですから、私が遭遇した特定の状況に代わるものを私に与えることはできません。しかし、多分あなたは私の全体的な思考を助けることができます。

4

2 に答える 2

43

さて、あなたの最初の例から:

var _obj = {
    property: value,
    method1: function() {
      // do stuff
    },
    method2: function() {
      // use property
      var prop = this.property; 
      // call method1
      this.method1(); 
    }
  };

それがthis価値の目的です。

さて、あなたができないことは、オブジェクトリテラル構文の他の場所から「構築中」オブジェクトのプロパティを参照することです。(構文的に不可能であるため、例を示すのは困難です。)それを実行したい場合は、1つ以上の個別の割り当てステートメントが必要です。

于 2012-06-06T16:28:31.473 に答える
11

何だと思う?あなたは単純なものを複雑にしています。Pointyの答えは良いですが、いくつかの理由からプロトタイプの方法の方が優れています。そのため、最後の方法を説明しています(むしろ修正を加えています)。このフィドルを確認してください

var MyObj = function(name) {
  this.name = name;
};

MyObj.prototype = {
  called_often: function() {
    // lots more code than just the following
    return 'VALUE'; //document.getElementById('someID').value;
  },

  global_default: 'value', // can be changed, so need to pull value when run

  does_stuff: function(value) {
    var str = this.global_default + value, // can't access global_default on its own
        input = this.called_often(), // doesn't work; MyObj.prototype.called_often() DOES
        name = this.name; // 'this' used in the prototype doesn't work
                          // even within a created object
    return name + input + str;
  }
};

var obj = new MyObj('Bob');
于 2012-06-06T16:34:50.597 に答える