18

いくつかのパラメーターを渡すクラスがある場合:

class Foo

  constructor: (parameters) ->

  @bar = parameters.bar
  @moo = parameters.moo

クラスは次のように作成されます。

foo = new Foo(bar: 2, moo: 8)

私の質問は、渡される変数が存在するかどうかをコンストラクターで検出し、デフォルトを設定しない場合に最もエレガントな方法は何ですか。私がjavascriptでそれを行う方法は次のとおりです。

this.bar = ( parameters.bar !== undefined ) ? parameters.bar : 10;

ここで、10 がデフォルトです。

ご協力いただきありがとうございます :)

良い答え - 最高のものを要約するだけです:

パラメータが存在するかどうかを検出し、存在しない場合はデフォルトを定義するには、javascript で次のようにします。

this.bar = ( parameters.bar !== undefined ) ? parameters.bar : 10;

そして、コフェスクリプトでは次のとおりです。

@bar = parameters.bar ? 10

とてもエレガントでコンパクト!

4

5 に答える 5

30

存在演算子を使用できます:

class Foo
  constructor: (options = {}) ->
    @bar = options.bar ? 10
    @moo = options.moo ? 20

そのコンストラクターは次のようにコンパイルされます。

// Compiled JS.
function Foo(options) {
  var _ref, _ref1;
  if (options == null) {
    options = {};
  }
  this.bar = (_ref = options.bar) != null ? _ref : 10;
  this.moo = (_ref1 = options.moo) != null ? _ref1 : 20;
}

同等の代替手段は、オプション オブジェクトをすぐに破棄し (したがって、不要な名前を避ける)、それらのオプションが渡されなかった場合に備えて既定値を設定することです。

class Foo
  constructor: ({@bar, @moo} = {}) ->
    @bar ?= 10
    @moo ?= 20

オプションを指定してオブジェクトを渡すことは JS コードの一般的なパターンであるため、一部のライブラリにはこれに役立つ便利なユーティリティ関数があります。たとえば、アンダースコアは を提供します_.defaults。これにより、非常に読みやすいコードになると思います。

class Foo
  constructor: ({@bar, @moo} = {}) ->
    _.defaults @, bar: 10, moo: 20

Underscore を使用して$.extendいない場合は、(とにかく jQuery を使用しないのは誰ですか?):

class Foo
  defaults = bar: 10, moo: 20
  constructor: (options = {}) ->
    {@bar, @moo} = $.extend {}, defaults, options

渡される唯一のオプションが有効なものであると信頼できる場合はextend、オブジェクトを直接使用することもできます (これにより、他のものと比較して非常に最小限の JS になります)。Foo

class Foo
  defaults = bar: 10, moo: 20
  constructor: (options = {}) ->
    $.extend @, defaults, options

そして、最後の代替手段は、にデフォルト値をFoo.prototype設定し、オプション パラメータに含まれる場合にのみ独自のプロパティとして設定することです。

class Foo
  bar: 10
  moo: 20
  constructor: ({bar, moo} = {}) ->
    @bar = bar if bar?
    @moo = moo if moo?

これにより、 のすべてのインスタンスがFoo独自の個別のプロパティを持つことを防ぎ、代わりにインスタンス間で同じプロパティを共有します。これは通常、メソッドで行われるのと同じです。@bar = bar if @bar isnt barパラメータ値がデフォルト値と異なる場合にのみ、これらのプロパティを割り当てることもできます。

ご覧のとおり、これを行うには非常に多くの方法があります。どれも完璧ではありません。すべてに長所と短所があるため、ニーズ/好み/その他に適したものを選択してください = D

于 2012-07-15T17:49:24.163 に答える
3

?=演算子を使用してこれを行うことができます。

class Foo
  constructor: (parameters) ->
   @bar = parameters.bar
   @bar ?= 10
   @moo = parameters.moo
   @moo ?= 20

ハッシュではなく位置引数を渡すことを気にしない場合は、デフォルトのパラメーター値を使用してこれを非常にエレガントに行うこともできます。

class Foo
  constructor: (@bar = 10, @moo = 20) ->

f = new Foo
于 2012-07-15T16:15:16.307 に答える
2

デフォルトのオブジェクトを定義して、このようなことを行うことができます..

 (parameters = {}) ->
   this[key] = parameters[key] ? defaults[key] for key, value of defaults

しかし、実際にはそのすべてを経験する必要はありません。デフォルト値を作成する最も簡単な方法は、プロトタイプの継承を使用することです...

class Foo
  bar: 10
  moo: 10
  constructor: (parameters = {}) ->
    this[key] = value for own key, value of parameters

上記を仮定すると:

a = new Foo();
a.bar # => 10
b = new Foo(bar: 50)
b.bar # => 50

コンストラクターを除いて、: で定義するすべてのプロパティは、オブジェクトのプロトタイプのプロパティになります。

クラス定義は、次の JavaScript に変換されます。

Foo = (function() {      
  Foo.prototype.bar = 10;      
  Foo.prototype.moo = 10;
  //etcetc
  return Foo;      
})();

それで遊びます。それが役立つことを願っています。

于 2012-07-15T16:43:44.987 に答える