解构函数的返回语句,但不要替换现有的变量

时间:2014-08-16 18:42:54

标签: javascript function variables coffeescript destructor

在CoffeeScript中,我喜欢在返回具有多个返回值的函数时使用解构赋值。与返回数组相比,它使得返回的内容更清晰。

例如,从JavaScript中的函数返回一个数组:

function getSumAndDiff(firstNumber, secondNumber) {
  var sum = firstNumber + secondNumber
  var difference = firstNumber - secondNumber

  return [sum, difference]
}

var values = getSumAndDiff(10, 5)
var sum = values[0]
var difference = values[1]

在CoffeeScript中,从函数返回一个对象:

getSumAndDiff = (firstNumber, secondNumber) ->
  sum = firstNumber + secondNumber
  difference = firstNumber - secondNumber

  {sum, difference}

{sum, difference} = getSumAndDiff(10, 5)

然而,问题是CoffeeScript方法取代了任何名为sumdifference的现有变量。因此,如果我连续多次运行此函数,那么它们将继续覆盖前一个函数。

当然,有几种方法可以解决这个问题,例如每次都将返回的变量分配给其他名称,如下所示:

{sum, difference} = getSumAndDiff(10, 5)
sum1 = sum
difference1 = difference

{sum, difference} = getSumAndDiff(11, 6)
sum2 = sum
difference2 = difference

但是有更清洁的方法吗?或者,当我需要连续多次运行这样的函数时,这可能是简单地返回数组的最佳解决方案?或者闭包有意义,还是过多的代码呢?我只是想知道是否有一些我可能会遗漏的东西,因为我认为必须有一种更清洁的方式,特别是使用CoffeeScript?或许我对此的一般处理方法存在缺陷,例如我应该只为每个函数设置一个返回值,以简化操作?

2 个答案:

答案 0 :(得分:1)

你现在拥有什么......

好的,我现在明白了。当你写:

getSumAndDiff = (firstNumber, secondNumber) ->
  sum = firstNumber + secondNumber
  difference = firstNumber - secondNumber

  {sum, difference}

函数getSumAndDifference返回一个关联数组(以及对象),其中包含变量名称和值的内容。这只是语法糖相当于:

{ 'sum': sum, 'diff': diff }

该关联数组是返回的值,然后使用 object destructing 来获取感兴趣的各个字段:

{sum, difference} = getSumAndDiff(10, 5)

这再次只是语法糖:

_obj =  getSumAndDiff(10, 5)
sum = _obj['sum']
diff = _obj['diff']

...现在,对于一些替代方案

1)别名对象解构

首先,正如您自己解释的那样,您可以使用“别名”对象销毁来将值作为另一个名称取回:

{sum:x, diff: y} = getSumAndDiff(10, 5)

这会将x设置为与返回对象的字段sum相同的值。 ydiff字段的值相同。

周围的句法糖:

_obj = getSumAndDiff(10, 5)
x = _obj['sum']
y = _obj['diff']

作为旁注,请再次注意{sum,diff}实际上是写{sum: sum, diff: diff}的快捷方式

2)阵列解构

另一种更简单的替代方法是不返回对象而是返回数组(更正式地说,数字索引数组):

getSumAndDiff = (firstNumber, secondNumber) ->
  sum = firstNumber + secondNumber
  difference = firstNumber - secondNumber

  [sum, difference]  ## <-- array [ ... ] not object { ... }

使用该语法,sumdiff将作为索引01的项目返回。一个数组。从调用者方面,您可以使用数组解构来提取这些值:

[sum, diff] = getSumAndDiff(10, 5)

由于数组是数字索引的,因此您不必担心字段名称。所以你也可以这样写:

[x, y] = getSumAndDiff(10, 5)
[sum2, diff2] = getSumAndDiff(10, 5)
...

答案 1 :(得分:0)

好的,所以我明白了。我知道我的问题不是最清楚的。真的,我一直在寻找一种简化代码的方法,而不是找到确切问题的精确解决方案。

我现在意识到,由于CoffeeScript的解构赋值实际上只是从返回值传递到全局范围的对象,基本上,我可以通过将变量传递给另一个变量来“重命名”现场变量。 (不是最好的解释......见下面的例子。)

例如,return { test }实际上仅仅意味着return { test: test }(我之前知道,但最终忘记了它意味着)。

所以,我可以代替{sum, difference} = getSumAndDiff(10, 5)而不是{sum: sum2, difference} = getSumAndDiff(10, 5)

这导致sum2被设置,而不是sum,如果之前已经设置了sum,则可以通过调用相同的函数来替换{ test }

我想是使用CoffeeScript的一个怪癖! (主要是{ test: test }表示{{1}}符号。)