在没有大括号的箭头函数中多个表达式的做法是什么?

时间:2018-02-25 12:59:13

标签: javascript ecmascript-6 functional-programming

我喜欢探索JavaScript的局限性,并想知道是否可以使用箭头函数,其中最后一个表达式将是return语句。

幸运的是,这是可能的,但在同一范围内设置变量有一些缺点。

[1,2,3,4,5].reduce((sum, element) => (const doubleSum=sum+sum, doubleSum+element));

返回未识别的标识符(指doubleSum)

解决方案是将其写为

let doubleSum; 
[1,2,3,4,5].reduce((sum, element) => (doubleSum=sum+sum, doubleSum+element));

所以现在没有卷曲的支持,我可以通过在函数中包含两个表达式来获得sum+sum+element的总和。这不是一个很好的示例用法,但它显示了如何使用没有大括号的2个表达式。

这样做的结果是57,因为它每次迭代只返回doubleSum+element。如果您想将其拆分为更易读的部分,这对计算非常有用。

另一个例子是记录每次迭代的结果,而不必使用大括号

[1,2,3,4,5].reduce((sum, element) => (console.log(sum), sum+sum+element));
//1
//4
//11
//26
//57

我真的很喜欢这种语法,但我想知道这是不好的做法,因为Arrow functions

没有提到它

4 个答案:

答案 0 :(得分:3)

  

我想知道这是不好的做法

是的,在数组函数范围之外声明doubleSum绝对是一种不好的做法。不要那样做。

  

另一个例子是使用不带花括号的console.log。我非常喜欢这种语法,但在Arrow函数

中没有提到它

是的,那是因为它不是箭头功能特有的。您只是在这里使用grouping syntaxcomma operator。在Processing and then returning usage example那里可以找到一些类似的用法。

答案 1 :(得分:1)

您所说的function nth_fact(nth){ var a = 1 while(nth_fact) if (nth_fact == 0 || nth_fact == 1){ break; result => result * nth_fact nth_fact => nth - 1 console.log() } } 称为逗号运算符(MDN entry)。

此运算符来自C语言,其中用例通常是多行变量(,)和特定宏(痛苦)的单行声明。

大多数现代语言都放弃了这个运算符,转而支持更高的抽象。

但即使我们跳过历史记录,我也会认为最佳实践的主要目标之一是可读性的属性。绝对不是保存一些按键的目标。

现在比较:

var i, j, k

let doubleSum; 
[1,2,3,4,5].reduce((sum, element) => (doubleSum=sum+sum, doubleSum+element));

其中一个样本将[1,2,3,4,5].reduce((sum, element) => { const doubleSum = sum + sum; return doubleSum + element; }); 声明为用于所有doubleSum次迭代的封闭变量,而另一个样本将reduce声明为每次迭代的局部变量。你认为哪一个表明意图更好?哪一个更容易重构而不必担心会破坏一些奇怪的案例?

使用日志记录示例,这不是很清楚。但是,将每个副作用(例如记录消息)放入单独的语句(以doubleSum结尾的行)通常被认为是一种好习惯。

想象一下:

;

但是,出于某种原因,someArray.map((element) => (console.log(element), doSomething(element))); 并没有按照您的预期运作。让我们添加一些日志记录:

doSomething

我们回到let intermediate; someArray.map((element) => ( console.log(element), intermediate = doSometing(element), console.log(intermediate), intermediate)); 那个奇怪的范围问题。这种变化甚至可能不那么容易 - 你想在intermediate回调中做一些事情,但事实上你必须在其范围之外创建一个变量才能做到这一点。现在想象一下,映射回调的复杂性会增加到几个这样的绑定变量。或者也许让if / else分支包含更多变量。然后你可能想把它提取到一个单独的函数:现在你需要再次推理所有绑定变量。

使用积木怎么样?

map

变为

someArray.map((element) =>
{
    console.log(element);
    doSomething(element);
});

现在,除了地图回调的内部块之外,我们没有必要编辑任何其他内容 - 更改更容易做到和推理。引入更多变量?没问题,他们都留在回调中。将回调提取为单独的函数?也没问题。这段代码的意图很明确。

答案 2 :(得分:0)

我认为您尝试实现的目标可能会让代码难以阅读。使用带有箭头功能的花括号没有任何问题。如果你想保持你的reduce回调清洁,你可能想要做这样的事情:

const doubleSumAndAddElement = (sum, element) => {
    console.log(sum);
    return 2 * sum + element;
}

[1,2,3,4,5].reduce(doubleSumAndAddElement);

答案 3 :(得分:0)

你无法在表达式中声明变量。但是你可以建立一个函数表达式并立即调用它(称为IIFE),这样你就可以得到本地参数:

 [1, 2, 3, 4].reduce((sum, value) => (double => double + value)(sum + sum));

如果那是有用的,那就是另一件事。