1

新しいクラスを作成して最終的に親this.propertyを呼び出すことなく、実行時およびインスタンスごとにオーバーライドするにはどうすればよいですか?doAnotherThing

var ThridPartyObject = function() {

    this.property = 'value';

    this.doOneThing= function() { /* */ }

    this.doAnotherThing= function() { /* */ }
};

運が悪い:

ThridPartyObject.prototype = {

    property: 'myvalue',

    doOneThing: function() { // Override only this function and call the other
        return this.doAnotherThing();
    }

};

編集property:存在する場合と存在しない場合があると言うのを忘れました。

これが必要なのは、backbone.js ですべてのモデル インスタンスのカスタム プロパティを定義する必要があり、一部の関数が元のバックボーンとは異なる方法で動作する必要があるためです。バックボーンが a を定義する方法は次のとおりですBackbone.Model(これ_.extendは underscore.js からのものです)。

  var Model = Backbone.Model = function(attributes, options) {
    var defaults;
    attributes || (attributes = {});
    if (options && options.collection) this.collection = options.collection;
    if (options && options.parse) attributes = this.parse(attributes);
    if (defaults = getValue(this, 'defaults')) {
      attributes = _.extend({}, defaults, attributes);
    }
    this.attributes = {};
    this._escapedAttributes = {};
    this.cid = _.uniqueId('c');
    this.changed = {};
    this._silent = {};
    this._pending = {};
    this.set(attributes, {silent: true});
    // Reset change tracking.
    this.changed = {};
    this._silent = {};
    this._pending = {};
    this._previousAttributes = _.clone(this.attributes);
    this.initialize.apply(this, arguments);
  };

  // Attach all inheritable methods to the Model prototype.
  _.extend(Model.prototype, Events, {
      // cut
  });
4

2 に答える 2

2

オブジェクトが真に「サード パーティ」であり、制御できない場合、その作成者は、プロトタイプの継承と互換性のないパターン (「クロージャ パターン」と呼ばれることもあります) を選択しています。ThirdPartyObjectインスタンスのプロパティをグローバルにオーバーライドすることはできません。これは、すべてThirdPartyObjectが構築時にpropertydoOneThing、および新しく割り当てられるためです。doAnotherThing

この場合、唯一の解決策は、オリジナルをラップする新しいファクトリ関数を作成することです。

function modifiedThirdPartyObjectFactory() {
    var x = new ThirdPartyObject();
    x.property = "myvalue";
    return x;
}

var mtpo = modifiedThirdPartyObjectFactory();

プロトタイプの継承を使用するパターン、次のように機能します。

function ThirdPartyObject() {
    this.property = "value";
}

ThirdPartyObject.prototype.doOneThing = function () {
};

ThirdPartyObject.prototype.doAnotherThing = function () {
};

このパターンは、コンストラクターでインスタンスプロパティ (通常はデータ) を設定します。一方、共有プロパティ (通常はメソッド) はプロトタイプに含まれます。元のコードはすべてのプロパティをインスタンス プロパティにしたため、変更がすべてのインスタンスに反映される結果となる変更可能な共有プロパティはありません。

于 2012-08-15T22:47:38.350 に答える
1

あなたは実際にそれについて後ろ向きに考えています。

プロトタイプは親クラスのようなものです。クラスベース言語の親クラスとまったく同じではありません (多くの違いがあります)。
ただし、この例では、プロパティ/メソッドを継承するために、プロトタイプが親クラスになります。

あなたが作るとき、あなたの問題のすべての意図と目的のために、それは子供ですFooFooこれを行う場合:

function Foo () { this.method = function () {}; this.property = {}; }
Foo.prototype.method = function () {};
Foo.prototype.property = {};
Foo.prototype.other_property = 3;

それは次のように言っているのと似ています:

PrototypeClass {
    public virtual property = {};
    public other_property = 3;
    public virtual method ( ) { }
}
Foo inherits BaseClass {
    public override property = {};
    public override method () {}
}

var foo = new Foo();

constructorforは、同じ名前を持つ内のチェーンのFooすべてを上書きしています。内部にメソッドまたはプロパティがないprototype場合、そのチェーンを通じて上流を調べますFoo inheritance/prototype

したがって、 のメソッド/プロパティをオーバーライドする場合は、 のインスタンスをオーバーライドするFoo必要new Foo()あります。

そのためのオプションは、ラッパーを構築することだけFooです... ...次のように:

function FooPlusPlus () {
    var foo = new Foo();
    foo.plus = function () { this.doSomething(); console.log(this.val); };
    foo.plusPlus = function () { foo.plus(); console.log(this.other_val); };
    return foo;
}

var fooPlusPlus = FooPlusPlus(); // ***NO NEW***

...または、既存のオブジェクト (「クラス」、「辞書」、関数、配列のいずれであっても) を単純に拡張する関数を作成し、それらを拡張したいプロパティ/機能を追加します。

var extendObj = function (subject, extensions) {
    var key = "";
    for (key in extensions) { if (extension.hasOwnProperty(key)) {
        subject[key] = extensions[key];
    }}
}


var regularFoo = new Foo();

extendObj(regularFoo, { awesomeFunc : function () { if (typeof this.doSomething === "function") { this.doSomething(); }}, coolProp : "Bob" });

JS は、Core オブジェクトを慎重に操作しなくても、文字列や数値がカスタム データを持つクラスのように動作することを期待しない限り、何でも継承できる自由を提供します。

于 2012-08-15T23:16:09.377 に答える