javascript - 与循环相比,使用函数有什么优点?

标签 javascript loops closures

函数式迭代器似乎正在取代 JS 中 for 循环的使用。

与 for/while 循环相比,传递诸如 mapreduce 之类的函数有什么优势?

var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
  return num * 2;
});

var doubles = [];
for (i = 0; i < numbers.length; i++) { 
    doubles[i] = numbers[i] * 2;
}

最佳答案

我不知道为什么您将 map 的使用称为“闭包”。闭包完全是另一回事。 map 是一个高阶函数——定义为对函数进行操作(获取或返回)的函数。这种编程风格可以粗略地称为“函数式”。

使用像map这样的函数有优点和缺点。正如一位评论者指出的那样,它更加紧凑:

function sum(array) {
  var sum = 0;
  for (var i = 0; i < array.length; i++) sum += array[i];
  return sum;
}

对比

function sum(array) {
  return array.reduce(add);
}

其中 addfunction add(a, b) { return a + b; }.

更紧凑意味着更具可读性并且更小的 bug 区域。使用名为 add 的函数也增强了可读性;我们很容易直觉到该操作就是将数组的元素相加。

基本上,所有数组函数都有 for 循环等效项,这需要设置更多变量并编写更多逻辑。例如,map

function map(array, fn) {
  var result = [];
  for (var i = 0; i < array.length; i++) result.push(fn(array[i]));
  return result;
}

这可以更紧凑地编写为 array.map(fn)

在许多情况下,我们可能已经定义了执行元素映射或我们想要执行的元素过滤的函数。在这种情况下,我们可以简单地使用 mapreduce 等函数。

map 及其 friend 还具有对稀疏数组友好的优点。例如:

var a = [];
a[1000000] = 1;

现在我们将每个元素加倍:

function double(array) {
  var result = [];
  for (var i = 0; i < array.length; i++) result.push(array[i] * 2); 
  return result;
}

这会循环一百万次并返回一个充满 NaN 的数组。相比之下

array.map(elt => elt*2)

仅对位置 1000000 处的单个元素进行操作,并根据需要返回稀疏数组。

功能性风格还为灵 active 提供了额外的可能性。假设我们想要概括乘法的想法。我可以编写一个高阶函数来创建一个将某个值乘以特定因子的函数:

function multiply(n) {
  return function(x) {
    return n * x;
  };
}

现在我可以写了

array.map(multiply(2))

这种程度的简洁性和表现力在 for 循环解决方案中很难实现。

forEachmap 等可能比 for 循环慢。如果您的代码在紧密循环中运行一百万次,这可能会成为一个问题。在现实世界中,这很少是一个问题。最好优先考虑代码的可读性和紧凑性。

但是,没有人强制您使用 mapfilter。在 ES7 或其他任何名称中,您将能够使用数组推导式以更易读的方式完成相同的事情:

[ for (i of array) if (i % 2) i + 1 ]

它结合了过滤器和 map 。

再远一点,如果您计划编写一个迭代数组的生成器,并从每个元素生成一些计算,您将需要使用 for 循环,因为无法从内部生成forEach 回调:

function *double(array) {
  for (var i = 0; i < array.length; i++) yield array[i]*2;
}

function *double(array) {
  array.forEach(elt => yield elt*2); // DOESN'T WORK!!
}

关于javascript - 与循环相比,使用函数有什么优点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34402198/

相关文章:

php - PHP 中的 FOR 循环性能

java - 从二维数组中顺序接收元素(Java)

Javascript Closure 和 WebRTC 回调问题

ios - 为什么 Swift 全局函数作为闭包捕获全局变量的特例?

javascript - jQuery/JS 查找提交表单的元素

javascript - 在指令模板中时,如何使 Angular ui-router ui-sref 工作?

javascript - 在 AngularJs 中动态添加 url 到脚本标签中

javascript - react : how to move a function out of the render() function?

python - 以特定格式编写和读取字典(Python)

javascript - 如何将对象用作函数和对象?