5

次の例は、goog.ui.Component を拡張するクラスを示しています。

クラスのプロパティは、以下に示すようにコンストラクターの外側で定義する必要がありますか、それともコンストラクターでのみインラインで定義する必要がありますか?

プロパティを null に初期化しても問題ありませんか?

goog.provide("org.something.SomeClass");

/**
 * @type {Object}
 * @private
 **/
org.something.SomeClass.prototype.anObject_ = null;

/**
 * @type {Element}
 * @private
 **/
org.something.SomeClass.prototype.anElement_ = null;

/**
 * @param {goog.dom.DomHelper=} opt_domHelper
 * @constructor
 * @extends {goog.ui.Component}
*/
org.something.SomeClass = function () {
    goog.ui.Component.call(this, opt_domHelper);

    this.anObject_ = {};
    this.anElement_ = new Element();
};
goog.inherits(org.something.SomeClass, goog.ui.Component);
4

2 に答える 2

3

Closure Libraryは、プロトタイプとコンストラクター関数内で定義されたプロパティを持つクラスを実装します。Closure Library のソース コードの学習に加えて、プロパティをプロトタイプで定義するかコンストラクタで定義するかを決定する際に考慮すべきいくつかの質問があります。

プロパティはクラスのインスタンスごとに一意ですか?

各インスタンスに固有のプロパティ (車の VIN 番号など) は、インスタンス間で共有すべきではないため、プロトタイプではなくコンストラクタで定義します。

/**
 * A car.
 * @param {string} vin The Vehicle Identification Number.
 * @constructor
 */
Car = function(vin) {

  /**
   * The Vehicle Identification Number.
   * @type {string}
   * @private
   */
  this.vin_ = vin;
}; 

プロパティの型は不変 (例: 文字列、ブール値、数値) または可変 (例: オブジェクト、配列) ですか?

不変のプロパティ型はインスタンス間で安全に共有できるため、プロトタイプで定義する必要があります。インスタンスが共有デフォルト値をオーバーライドする必要がある場合は、同じ名前のプロトタイプ プロパティをシャドウするインスタンス プロパティを追加できます。

/**
 * The number of cylinders in the engine.
 * @type {number}
 * @private
 */
Car.prototype.cylinders_ = 4;

/**
 * Sets the number of cylinders in the engine.
 * @param {number} cylinders The number of cylinders.
 */
Car.prototype.setCylinders = function(cylinders) {
  if (this.cylinders_ == cylinders) {
    // Since the number of cylinders has not changed, do not add a new
    // instance property to shadow the prototype property. Instead, continue
    // to use the prototype property.
    return;
  }

  // Defines cylinders_ property on the instance object that shadows
  // Car.prototype.cylinders_
  this.cylinders_ = cylinders;
};

/**
 * Gets the number of cylinders in the engine.
 * @return {number} The number of cylinders.
 */
Car.prototype.getCylinders = function() {
  return this.cylinders_;
};

次の例は、インスタンス プロパティの設定がプロトタイプ プロパティをどのように隠すかを示しています。

var myCar = new Car("1HGCM82633A004352");
alert(myCar.getCylinders()); // Alerts 4.

myCar.setCylinders(6);
alert(myCar.getCylinders()); // Alerts 6;

// Delete the instance property and let the prototype property
// "shine through".
delete myCar.cylinders_;
alert(myCar.getCylinders()); // Alerts 4;


プロパティ タイプが Array や Object などの変更可能な場合、ほとんどの場合、クラスのインスタンス間で同じ変更可能なプロパティ インスタンスを共有することは望ましくありません。したがって、変更可能なプロパティは、プロトタイプではなくコンストラクターで定義されることがよくあります。

プロパティを に初期化してもnullよろしいですか?

Closure Library にはプロパティが初期化される多くの例がありますがnull.、上記の例のようにデフォルトのシリンダー数を 4 に設定するなど、可能な場合は変数を有用なデフォルト値に初期化することをお勧めします。

于 2012-08-31T19:48:18.920 に答える
0

また、V8エンジンとクロージャーコンパイラーの最適化のためだと思います。すべてのオブジェクトが同じプロパティを持つ場合、V8 エンジンはクラスのようなインスタンスをキャッシュします (IO2012 トーク)。in プロトタイプですべてを宣言することにより、すべてのオブジェクト インスタンスは規則正しく同じプロパティを持ちます。または、明確なスタイルが必要なだけかもしれません。:-)

于 2012-09-04T13:16:11.840 に答える