我不知道为什么您会称其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); }
哪里add
是function add(a, b) { return a + b; }
。
更加紧凑意味着更易于阅读,并且表面积更小。使用命名的函数add
还可以增强可读性。我们可以很容易地看出操作是添加数组的元素。
基本上,所有数组函数都有for-loop等效项,它们需要设置更多的变量并编写更多的逻辑。例如,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)
。
在很多情况下,我们可能已经定义了执行元素映射或元素过滤的函数。在这种情况下,我们可以简单地按原样使用函数map
,reduce
等等。
map
并且它的朋友也具有对稀疏数组友好的优势。例如:
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上存在的单个元素进行运算,并返回一个稀疏数组。
功能风格还为灵活性提供了更多可能性。假设我们要推广乘以事物的想法。我可以编写一个高阶函数来创建一个将某个值乘以特定因子的函数:
function multiply(n) { return function(x) { return n * x; }; }
现在我可以写
array.map(multiply(2))
在for循环解决方案中,很难达到这种简洁和表达的水平。
forEach
和map
等都是可能比一个for循环慢。如果您的代码在紧密的循环中运行一百万次,则可能会出现问题。在现实世界中,这很少是一个问题。最好优先考虑代码的可读性和紧凑性。
但是,没有人强迫您使用map
或filter
。在ES7或它将被称为的任何版本中,您将能够使用数组推导以更易读的方式完成同一件事:
[ for (i of array) if (i % 2) i + 1 ]
结合了过滤器和地图。
在更远的地方,如果您打算编写一个在数组上迭代的生成器,并从每个元素产生一些计算,则将需要使用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!! }