我不知道爲什麼你會打電話給使用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; }
。
更緊湊意味着更易讀和更少的表面區域的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)
。
在很多情況下,我們可能已經定義了函數來進行元素映射或者我們想要做的元素過濾。在這種情況下,我們可以簡單地使用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)
僅是存在於百萬位置,並返回一個稀疏陣列作爲一個希望單個元件上進行操作。
功能風格也爲靈活性打開了額外的可能性。假設我們想概括一下乘法事物的概念。我可以寫一個高階函數來創建它通過特定的因素乘以某個值的函數:
function multiply(n) {
return function(x) {
return n * x;
};
}
現在我可以寫
array.map(multiply(2))
簡潔和表現的這種水平將是硬在for-loop解決方案中實現。
forEach
and 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!!
}
呃,這不是關閉,這是什麼方法呢? 'map'和'reduce'對數組做了特定的事情,它們不僅僅像'for'循環那樣迭代? – adeneo
簡潔性(使用es6中的箭頭funcs會更好) – raina77ow
如果您不喜歡它們,則不必使用它們,但大多數情況下都可以在不使用新的(ish)數組方法的情況下完成。 – adeneo