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

时间:2015-08-19 06:23:09

标签: javascript coffeescript associative-array

当要定义此哈希中的默认值时,我想将哈希(关联数组,对象)传递给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' } */

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

问题

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

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

Vanilla JS Solution

然而,承认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

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

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