对象的解构分配 - 有没有办法匹配对象的其余部分?类似于解构数组时的splat

时间:2013-11-30 06:33:30

标签: coffeescript

在Coffeescript中,当解构数组时,您可以执行以下操作:

[hello, foo, theRest...] = ['world', 'bar', 'attribute1', 'attribute2']

# hello = 'world'
# foo = 'bar'
# theRest = ['attribute1', 'attribute2']

我希望做以下事情(不起作用):

{hello, foo, theRest...} = {
  hello: 'world'
  foo: 'bar'
  other: 'attribute1'
  another: 'attribute2'
}

# hello = 'world'
# foo = 'bar'
# theRest = { other: 'attribute1', another: 'attribute2' }

可悲的是,我在文档中看不到有关此案例的任何内容。我的想法是,我想抓住我不知道的所有内容,并可能将其传递给另一个能够处理它们的函数。

3 个答案:

答案 0 :(得分:2)

你是对的,在CoffeeScript中没有这样的东西。使用数组,很容易做到:

[a, b, c...] = array

因为JavaScript数组本身支持slice提取数组的一部分;在本地JavaScript中没有像slice这样的对象,因此CoffeeScript必须内联一个循环来伪造不​​存在的Object#slice方法。使用常量键进行复杂的对象重构,例如:

{o1: {i, o2: {j, k}}} = obj

用于从i中提取jkobj很容易,因为结构在“编译”时已知,因此JavaScript很容易生成。当然,不支持...对象的理由只是推测。

如果你想用对象做theRest...那么你可以编写自己的函数来做到这一点,如下所示:

deobj = (obj, keys...) ->
    ret = (obj[k] for k in keys)
    ret.push(rest = { })
    rest[k] = v for k, v of obj when k !in keys
    ret
[hello, foo, theRest] = deobj(obj, 'hello', 'foo')

演示:http://jsfiddle.net/ambiguous/r8hMa/

如果您不介意在此过程中咀嚼obj,您可以将其简化为:

deobj = (obj, keys...) ->
    ret = [ ]
    for k in keys
        ret.push(obj[k])
        delete obj[k]
    ret.push(obj)
    ret

演示:http://jsfiddle.net/ambiguous/rvC9g/

答案 1 :(得分:1)

lodash有一个omit函数,http://lodash.com/docs#omit

Creates a shallow clone of object excluding the specified properties. Property names may be specified as individual arguments or as arrays of property names. If a callback is provided it will be executed for each property of object omitting the properties the callback returns truey for. The callback is bound to thisArg and invoked with three arguments; (value, key, object).

underscore可能也有相同的内容。

咖啡'一个班轮'是:

therest={};for k,v of obj when k not in ['hello','foo']  then therest[k]=v

两者都需要省略键名列表。我想不出使用赋值中使用的名称的方法。

答案 2 :(得分:0)

对于使用splats进行解构分配,只能使用数组表示法。无法使用对象嵌套的原因很简单 - 当您使用对象表示法来构造赋值时,您需要事先知道属性名称。 正如您可能已经想到的那样,这将起作用。

{hello, foo} = {
  hello: 'world'
  foo: 'bar'
  other: 'attribute1'
}

但这不会。

{hello_new, foo_new } = {
  hello: 'world'
  foo: 'bar'
  other: 'attribute1'
}

第二个示例不起作用的原因是属性名称不匹配。对于您的示例,最好的方法是使用数组样式:

[hello, foo, theRest...] = ['world', 'bar', 'attribute1', 'attribute2']

这样,hello和foo是在当前函数范围中定义的变量。而theRest是数组['attribute1', 'attribute2']

或者,你可以使用下划线来省略键名为hello和foo的kv对_.omit others = _.omit(obj, hello, foo)