5

JavaScriptでは、ある種のextend関数を使用してオブジェクトを作成できます。

たとえば、一連のパブリックメソッド(、、、、、など)を公開するクラスがあるとobservableします。getpushsetincrementget

この場合、observableはEventEmitterでもあるため、パブリックメソッドのセット(、、、など)も公開されemitます。onremoveListener

これらのクラスは両方とも、状態を格納する内部アンダースコアプレフィックス付きプロパティを持っています。eventemitterは_events、イベントハンドラーと監視可能な用途_state_id保存し、状態とIDを保存するために使用します。

さて、このようなオブジェクトコンポジションを使用してモデルを作成すると

var Model = extend({}, Observable, {
    constructor: function () {
        // Oops, I was supposed to know Observable uses the _state name already
        this._state = { ... }
    },
    someMethod: function () { ... }
})

Observableすでに_state内部プロパティを使用しており、名前の衝突が発生しているため、これにより問題が発生します。

ミックスインが安全に機能するために、どのオブジェクトがどの内部プロパティに依存しているかを「知る必要がある」だけでは醜いと思います。

同じ内部プロパティ名を使用する2つのオブジェクトが混在しないようにするにはどうすればよいですか?

理想的には、これはES6のプライベート名で解決されますが、まだそれを行うことはできず、パフォーマンスを損なうことなくそれらをエミュレートすることはできません。パフォーマンスに大きなペナルティがないES6名エミュレーションを提供できない限り、これらのソリューションには興味がありません。

別の方法はクロージャを使用することbindですが、そうすると、すべてのインスタンスの関数を再作成することになり、パフォーマンスが大幅に低下します。もう1つの方法は、内部プロパティを__eventEmitter_eventsおよびとして名前空間化すること__observable_stateです。それは単に醜く、名前空間の衝突の可能性を減らします、それはそれを削除しません。

4

1 に答える 1

0

簡単な解決策は「名前空間」です

var state = "Model@v0.1.3~state";
var Model = extend({}, Observable, {
    constructor: function () {
        // Nice, I used a namespace and don't clash with "Observable@v0.2.3~state"
        this[state] = { ... }
    },
    someMethod: function () { ... }
})
于 2013-01-16T08:36:14.993 に答える