【问题标题】:Coffeescript pass associative array with default parameters to the functionCoffeescript 将带有默认参数的关联数组传递给函数
【发布时间】:2015-08-19 06:23:09
【问题描述】:

当定义了这个散列的默认值时,我想将散列(关联数组,对象)传递给咖啡脚本中的函数。将哈希对象传递给函数会将这些值与默认值合并。如何实现?

var uiDialog = function({url = 'secret', data = 'something'}) {
  /* body of the function */
};

uiDialog({data:null,method:'GET'}); /* result arguments are { url: secret, data: null, method: 'GET' } */
uiDialog({url:'myURL',method:'GET'}); /* result arguments are { url: 'myURL', data: 'something', method: 'GET' } */

【问题讨论】:

    标签: javascript coffeescript associative-array


    【解决方案1】:

    如果您可以访问 jQuery,请尝试:$.extend({}, yourDefaultsOptions, functionOptions)

    如果您没有,您可以尝试手动操作。这是一个示例方法

    defaults = { a: 1, b: 3 }
    funcOpts = { a: 2 }
    final    = {}
    
    for key, value of defaults
      final[key] = value
    
    for key, value of funcOpts
      final[key] = value
    
    console.log(defaults)
    console.log(funcOpts)
    console.log(final)
    

    【讨论】:

      【解决方案2】:

      问题

      问题在于 Coffeescript 支持默认函数参数和解构赋值,但不能同时支持。允许更多代码重用和更复杂结构的最简单解决方案是让 coffeescript 进行解构,并自己承担处理默认参数的任务。幸运的是,这很容易,这要归功于 jQuery 的 extend(第一个解决方案)或该方法的 polyfills(第二个解决方案)。

      jQuery 解决方案

      我冒昧地稍微重写了您的代码,并且为了您的方便,我构建了一个有效的 JSFiddle:http://jsfiddle.net/scarl3tt/jkLjxyqe/

      do ->
          class UiDialog
              _default =
                  url: 'secret'
                  data: 'something'
              constructor: (options) ->
                  {@url, @data, @method} = $.extend({}, _default, options)
      
          dlg1 = new UiDialog
              data: null
              method:'GET' # result arguments are { url: secret, data: null, method: 'GET' }
          dlg2 = new UiDialog
              url: 'myURL'
              method: 'GET' # result arguments are { url: 'myURL', data: 'something', method: 'GET' }
              
          $('body').append("<div><h1>dlg1</h1><pre>#{JSON.stringify dlg1}</pre>")
          $('body').append("<div><h1>dlg2</h1><pre>#{JSON.stringify dlg2}</pre>")
          return
      

      原版JS解决方案

      然而,承认 jQuery 不属于每个项目,一个好的解决方案是定义一个做同样事情的方法。我在第二个示例中提供了一个常见的extend polyfill 的咖啡脚本端口。这不是最有效的,但它很简洁:http://jsfiddle.net/scarl3tt/uq4tu6y1/

      do (w=window) ->
          utils = (w.utils = w.utils || {})
          utils.extend = (target, others...) ->
              for source in others
                  for name in Object.getOwnPropertyNames(source)
                      target[name] = source[name]
              return target
          
          class UiDialog
              _default =
                  url: 'secret'
                  data: 'something'
              constructor: (options) ->
                  {@url, @data, @method} = utils.extend({}, _default, options)
      
          dlg1 = new UiDialog
              data: null
              method:'GET' # result arguments are { url: secret, data: null, method: 'GET' }
          dlg2 = new UiDialog
              url: 'myURL'
              method: 'GET' # result arguments are { url: 'myURL', data: 'something', method: 'GET' }
              
          $('body').append("<div><h1>dlg1</h1><pre>#{JSON.stringify dlg1}</pre>")
          $('body').append("<div><h1>dlg2</h1><pre>#{JSON.stringify dlg2}</pre>")
          return
      

      请注意,我的 vanilla 解决方案确实包含并使用了 jQuery,但这仅仅是为了便于打印结果。实际上并不需要让它工作。

      此外,为了清楚起见,我将 extend polyfill 放在 window.utils 命名空间中,而不是 window.$ 中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多