繁体   English   中英

Coffeescript将具有默认参数的关联数组传递给函数

[英]Coffeescript pass associative array with default parameters to the function

当定义此哈希中的默认值时,我想将哈希(关联数组,对象)传递给coffeescript中的函数。 将散列对象传递给函数将使用默认值合并这些值。 我该如何实施?

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' } */

如果您有权使用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)

问题

问题在于,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的coffeescript端口。 它不是最有效的,但是它很简洁: 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

请注意,我的原始解决方案确实包含并使用了jQuery,但这只是为了轻松打印结果。 实际上并不需要使其工作。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM