JavaScriptの「クラス」のミックスイン

複数の場所で同じコードを作成するのは苦痛です。 今日は、クラスの繰り返しについていくつかの言葉を書きます。 人々は長い間解決策を考え出しています-同じメソッドとプロパティを共通の基本クラスに入れて、もしなければ、不純物を使うことができます。 JavaScriptにはこのパターンの実装が100万個あります。mixinが継承チェーンに含まれる場合のアプローチについて詳しく説明します。



問題は写真にあります



問題を視覚化することから始めましょう。 2つの基本クラスがあり、それらから2つの子クラスが継承されているとします。







ある時点で、同じ機能の必要性が子クラスに現れます。 通常のコピーと貼り付けは、図では次のようになります。







多くの場合、この機能は親クラスとは関係がないため、基本クラスに配置することは非論理的で間違っています。 ミックスイン-別の場所に取り出してください。 言語の観点から見ると、ミックスインは共通のオブジェクトになる可能性があります。







それでは、記事全体が書かれた瞬間、つまりミックスインをクラスに適切に練り込む方法について説明しましょう。



私自身の経験に基づいて、最も便利な方法は、ミックスインに基づいて一時クラスを作成し、それを継承キューに置き換えることです。







このアプローチの長所





コードを書く



以降のすべての例では、特定の実装( Backbone.Mixライブラリ)が使用されます。 コードを見ると、非常にシンプルであることがわかるので、お気に入りのフレームワークに簡単に適合させることができます。



実際の継承チェーンに埋め込まれたミックスインの使用方法を見て、実際にこのアプローチの利点を体験してみましょう。 あなたがサイトを書いていると想像してください))そしてあなたのサイトには、閉じることができるさまざまなものがあります-ポップアップ、ヒントなど。 彼らはすべて、CSSクラスをclose



て要素を非表示にして要素のクリックをリッスンする必要があります。 このためのミックスインは次のようになります。



 var Closable = { events: function () { return { 'click .close': this._onClickClose }; }, _onClickClose: function () { this.$el.hide(); } };
      
      





介入します!!!



 var Popup = Backbone.View.mix(Closable).extend({ // -   });
      
      





とても簡単ですね。 これで、継承チェーンは次のようになります。









このようなスキームにより、混合先のクラスのミックスインからメソッドを再定義および再定義することが非常に簡単になります。 たとえば、閉じるときにPopup



がコンソールに何かを書き込むようにできます。



 var Popup = Backbone.View.mix(Closable).extend({ _onClickClose: function () { this._super(); console.log('Popup closed'); } });
      
      





以下、例では、 backbone-superライブラリを使用します



干渉しない不純物..



...しかし、彼らは助けます。 時々、こねるのは弱くなく、1つのミックスインが不可欠です。 たとえば、私たちがカッコイイ人で、IndexedDBにログを書き込むと想像してください。また、このための独自のLoggable



がありますLoggable







 var Loggable = { _log: function () { //   IndexedDB } };
      
      





次に、ポップアップによって2つのミックスインに干渉します。



 var Popup = Backbone.View.mix(Closable, Loggable).extend({ _onClickClose: function () { this._super(); this._log('Popup closed'); } });
      
      





構文は複雑ではありません。 図では、次のようになります。







ご覧のように、継承チェーンは、ミックスインを接続する順序に応じて整列します。



依存ミックスイン



今、私たちのアナリストが私たちに近づき、ポップアップ、ヒントのすべての閉鎖に関する統計を閉じたいと言っている状況を想像してください。 もちろん、サイトで登録を行ったときから、そのような場合のTrackable



は長い間ありました。



 var Trackable = { _track: function (event) { //    -    } };
      
      





Trackable



Closable



をリンクしたい、あるいはClosable



依存する必要があるのは驚くことではありません。 この図では、次のようになります。







そして、継承チェーンでは、 Trackable



Closable



よりも前にある必要がありClosable











依存関係を持つミックスインのコードは少し複雑になります。



 var Closable = new Mixin({ dependencies: [Trackable] }, { events: function () { return { 'click .close': this._onClickClose }; }, _onClickClose: function () { this.$el.hide(); this._track('something closed'); // <-   } });
      
      





しかし、それほど複雑ではありません。依存関係を記述できる場所ができました。 これを行うには、追加のラッパークラスであるMixin



を導入する必要があり、 Mixin



自体は単なるオブジェクトではなく、このクラスのインスタンスになりました。 この場合、mixin接続自体は変更されないことに注意してください。



 var Popup = Backbone.View.mix(Closable, Loggable).extend({ … });
      
      





ミックスインを正しくドキュメント化する



WebStormは優れたミックスインをサポートしています。 JSDocを正しく記述すれば十分であり、プロンプト、オートコンプリート、コードの一般的な構造の環境による理解が大幅に向上します。 環境は、タグ@mixin



および@mixes



理解します。 文書化されたClosable Closable



およびPopup



クラスの例を見てみましょう。



 /** * @mixin Closable * @mixes Trackable * @extends Backbone.View */ var Closable = new Mixin({ dependencies: [Trackable] }, /**@lends Closable*/{ /** * @returns {object.<function(this: Closable, e: jQuery.Event)>} */ events: function () { return { 'click .close': this._onClickClose }; }, /** * @protected */ _onClickClose: function () { this.$el.hide(); this._track('something closed'); } }); /** * @class Popup * @extends Backbone.View * @mixes Closable * @mixes Loggable */ var Popup = Backbone.View.mix(Closable, Loggable).extend({ /** * @protected */ _onClickClose: function () { this._super(); this._log('Popup closed'); } });
      
      





多くの場合、特定の祖先を持つクラス用にミックスインが作成されます。 Backbone.View



から継承されたクラス用に記述されたClosable



、決して例外ではありません。 この状況では、 @extends



明示的に指定しない限り、環境はこの先祖のメソッド呼び出しがmixinコードのどこから来たかを理解しません。



 /** * @mixin Closable * @mixes Trackable * @extends Backbone.View */ var Closable = new Mixin(...);
      
      





これで、おそらくすべて、幸せな介入!



私のブログの英語版

Backbone.Mixライブラリ

同じ作者による別のコード: backbonex

ミックスインを思いつくときにjQueryヌードルをどのように見せるか? 英語で すぐにコード

私のtwitter (プロコードのみ)



All Articles