解构类构造函数中的参数列表 - Coffeescript

Jam*_*ron 18 coffeescript

如果我有一个类,我将一些参数传递给:

class Foo

  constructor: (parameters) ->

  @bar = parameters.bar
  @moo = parameters.moo
Run Code Online (Sandbox Code Playgroud)

该类创建如下:

foo = new Foo(bar: 2, moo: 8)
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果传递的变量存在,如果不设置默认值,在构造函数中检测的最优雅方法是什么.我在javascript中这样做的方式是:

this.bar = ( parameters.bar !== undefined ) ? parameters.bar : 10;
Run Code Online (Sandbox Code Playgroud)

其中10是默认值.

谢谢你的帮助 :)

好的答案 - 只是为了总结最好的:

为了检测参数是否存在并定义默认值(如果不存在),在javascript中是:

this.bar = ( parameters.bar !== undefined ) ? parameters.bar : 10;
Run Code Online (Sandbox Code Playgroud)

在coffescript中是:

@bar = parameters.bar ? 10
Run Code Online (Sandbox Code Playgroud)

如此优雅和紧凑!

epi*_*ian 30

您可以使用存在运算符:

class Foo
  constructor: (options = {}) ->
    @bar = options.bar ? 10
    @moo = options.moo ? 20
Run Code Online (Sandbox Code Playgroud)

该构造函数编译为:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

一个等价的替代方法是立即破坏选项对象(因此避免使用不必要的名称),然后设置默认值以防这些选项未被传递:

class Foo
  constructor: ({@bar, @moo} = {}) ->
    @bar ?= 10
    @moo ?= 20
Run Code Online (Sandbox Code Playgroud)

由于传递带有选项的对象是JS代码中的常见模式,因此一些库具有有用的实用功能,可以帮助解决这个问题.例如,Underscore提供了_.defaults,我认为这会产生相当可读的代码:

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

如果您不使用Underscore,还有$.extend(谁不使用jQuery?):

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

另一种方法是extendFoo对象直接,如果你相信,那将被传递的唯一选择是有效的人(这会导致相当小JS相比于其他的):

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

最后一种方法是在默认值中Foo.prototype设置默认值,如果它们出现在options参数中,则只将它们设置为自己的属性:

class Foo
  bar: 10
  moo: 20
  constructor: ({bar, moo} = {}) ->
    @bar = bar if bar?
    @moo = moo if moo?
Run Code Online (Sandbox Code Playgroud)

这可以防止所有实例Foo拥有自己的单独属性,而是在实例使用默认值时共享相同的属性,这通常与方法相同.您也可以@bar = bar if @bar isnt bar仅在参数值与默认值不同时分配这些属性.

如您所见,有很多方法可以做到这一点.它们都不是完美的,它们都有它们的优点和缺点,所以尽量选择一个更适合你的需求/品味/无论什么= D