CoffeeScriptの継承の改善

CoffeeScriptは、クラスの優れたプロトタイプ抽象化をJSにもたらしました。

よく知られている継承モデルを実装し、キャッシュレジスタメソッドの継承で補完することにより、

プロトタイプチェーンを知らなくても、クラス階層を簡単に構築できます。

しかし、このモデルは改善できます。



上記の方法では、既存の方法を完全に置き換えることはできませんが、

__proto__



プロパティを使用するため、一部のJS実装では使用できません。


ただし、作業中に継承の可能性を大幅に拡大することができます

メインモデルの上に。



コーヒーコンストラクターのプロトタイプのチェーンを作成することに加えて、次のコードを使用します

クラスのプロパティを継承するには:



 for key of parent child[key] = parent[key] if __hasProp_.call(parent, key)
      
      





つまり、すべてのプロパティが単純にコピーされます。 この継承では、柔軟性が失われます。



最も簡単な例は、祖先のメソッドを変更するときに、

継承されたクラス。 また、列挙不可能なプロパティは継承されません。



クラスプロパティもチェーンで継承されると、はるかに良いでしょう。

プロトタイプ。 必要なのは、コーヒーを継承した後にクラスを削除することです

すべてが継承されます:) child.__proto__ = parent



を設定します。



この継承により、子クラスは祖先のすべてのプロパティにアクセスできます。

オーバーライドすることもできます。 しかし、実装する機会があります

プロパティが属するという事実に基づいた興味深い機能

オブジェクトそのものではなく、プロトタイプ。



1つの例は、クラスインスタンス変数です。

UPD:すべて同じですが、変数はインスタンスではなくクラスを参照することを明確にします。

クラスインスタンス変数。 1つのクラスのプロパティとしてのみ使用できます。



 Object.defineProperty Parent, 'test', get: -> @_test if @hasOwnProperty '_test' set: (val) -> @_test = val Parent.test = 1 Parent.test # => 1 Child.test # => undefined Child.test = 2 Parent.test # => 1 Child.test # => 2
      
      





継承に対するこのアプローチは、 coffee_classkitパッケージの中心にあります。

このパッケージには、Rubyから取得したクラスを操作するためのメソッドも実装されています。

append_features



使用、 append_features



を使用したextend_object





inherited, included, extended



フック。 ここでは詳細に説明しません。

それらはルビーの類似物と同じで、カムケースの名前だけです。

Rubyに馴染みのない人は、難なくすべてがソースから理解されることを願っています

特にメソッドは6行以下であるためです。



すべての機能は、通常のクラス宣言構文を使用して利用できます。

 classkit = require 'coffee_classkit' class Child extends Parent classkit.extendsWithProto @ classkit.include @, Mixin
      
      





便宜上、パッケージには、構成にこれらすべてのメソッドを含むクラスがあります。

クラスを継承すると、より明示的で馴染みのある形式でそれらを使用できます。



 class Example extends classkit.Module @extendsWithProto() @include Mixin
      
      





パッケージには、 ActiveSupport::Concern



類似物も含まれていますActiveSupport::Concern







 class Mixin extends classkit.Module @extendsWithProto().concern() @includedBlock: -> #      @instanceVariable 'test' class @ClassMethods someClassMethod: -> someInstanceMethod: -> class Base extends classkit.Module @include Mixin @someClassMethod() (new Base).someInstanceMethod()
      
      





より簡単な例は、リポジトリ内のテストにあります。



説明されたアプローチを使用して、モジュラーを書くことが可能になります

グローバルな名前空間に侵入することのないオブジェクト指向コード。

詳細な例は、プロジェクトの概要で見ることができます。

CoffeeClasskitを使用して書かれています。



All Articles