CoffeeScriptを使用してクラスを拡張する方法はありますが、構築引数をsuperに渡す方法はありますか?クラスを拡張し、すべてのコンストラクタ引数をスーパーに渡します
例:
class List extends Array
# Some other stuff to make it work...
list = new List(1,2,3)
console.log list
[1, 2, 3]
CoffeeScriptを使用してクラスを拡張する方法はありますが、構築引数をsuperに渡す方法はありますか?クラスを拡張し、すべてのコンストラクタ引数をスーパーに渡します
例:
class List extends Array
# Some other stuff to make it work...
list = new List(1,2,3)
console.log list
[1, 2, 3]
class List extends Array
constructor: ->
@push arguments...
toString: ->
@join('-')
list = new List(1, 2)
list.push(3)
list.toString()
=>
'1-2-3'
一般的に、これは追加コードなしで動作します。その配列はconstructor
方法はありません
class A
constructor: ->
console.log arg for arg in arguments
class B extends A
new B('foo') # output: 'foo'
、問題ではない:親のコンストラクタを明示的に上書きされない限り使用されている問題だけではArray
ある
coffee> Array.constructor
[Function: Function]
は単なる奇妙です。配列は原則的に「単なるオブジェクト」ですが、実際には配列は別々に格納されます。したがって、コンストラクタを配列ではないオブジェクトに適用しようとすると(たとえそれがinstanceof Array
テストに合格しても)、動作しません。
このように、Acornのソリューションを使用できますが、実際には、実際の配列が必要なものにList
を渡した場合、他の問題が発生する可能性があります。そのため、ネイティブオブジェクト型からの継承を使用するのではなく、配列インスタンスのラッパーとしてList
を実装することをお勧めします。
我々は、件名に1点の非常に重要な明確化いる間:あなたは、それ自体でsuper
を使用し、は、すべての引数を渡すないこと!この動作はRubyから借用されています。 なし引数でコンストラクタ '
class B extends A
constructor: ->
super()
がA
を起動する一方、コンストラクタ' だから、
class B extends A
constructor: ->
super
はA
へのすべての引数に沿って渡します。
すばらしい説明をありがとう! '' Listを配列インスタンスのラッパーとして実装することをお勧めします。 ''これをどうやってやりますか?あなたが時間を持っているなら、短い例が大いに評価されるでしょう! – Acorn
さて、コンストラクタが '@arr = Array :: slice.call arguments、0'(argumentsメソッドをオブジェクトに変換する標準的なメソッド)のように見えるということは、配列メソッドのそれぞれを実装するということです単純なパススルーとして(例えば 'push: - > @ arr.push.apply arr、arguments'、' toString: - > @ arr.toString() '、...)、そして最後に独自の' List'メソッド。 –
ああ、うわー、すべてのメソッドを個別に渡す。ちょっと面倒だね:) – Acorn
JavaScriptの私の調査では、動的な数のコンストラクタ引数を持つクラスを作成するための一般的な方法が必要でした。前述のように、これは私が知っている限り配列に対しては機能しません。これは、コーヒースクリプトスタイルのクラスでのみ機能します。引数の動的数の特定の機能を呼び出す
は.apply
args = [1, 2, 3]
f = measurement.clone
f.apply measurement, args
を通してクラスが変数に保存されたクラスを拡張することができる十分に容易です。その結果、新しいサブクラスを返す関数を書くことができます。一緒にすべてを置く
classfactory = (f) ->
class extension extends f
我々は、スーパークラスのコンストラクタにで我々apply
引数の新しいサブクラスを返す関数を作成することができます。
classwitharguments = (f, args) ->
class extension extends f
constructor:() ->
extension.__super__.constructor.apply @, args
この新工場
args = [1, 2, 3]
instance = new (classwitharguments Measurement, args)
思考を使用するには?コメント?提案?制限事項私は考えなかった?お知らせ下さい。
CoffeeScriptでextends
を使用すると、スーパークラスもCoffeeScriptになると予想されます。非CSクラスを使用している場合(例:元の質問にArray
が含まれていると、問題が発生する可能性があります。
これは私の一般的なケースを解決しました。おそらくコンパイルされたJSで使用されることを意図していない_super
を使用しているので、ちょっとハックします。
class MyClass extends SomeJsLib
constructor: ->
_super.call @, arg1, arg2
それとも、単に発信者からの引数パススルーする場合:
class MyClass extends SomeJsLib
constructor: ->
_super.apply @, arguments
は、分離された二つにこの質問を分割するために素晴らしいと思いません。 superへのコンストラクタ引数の一般的な渡しの最初のもの、 'Array'の奇妙な振る舞いに関する第2のものです。 – Mitja