JavaScript 中 forEach、map、filter 詳細
1、forEach
和map
能實現的功能相似
2、forEach
、map
、filter
都能實現對原陣列的修改
3、forEach
沒有返回值,map
有返回值,filter
有返回值
forEach
forEach()
方法對陣列的每個元素執行一次提供的函式。
語法:
array.forEach(callback(currentVal, index, array) { // do something }, thisArg) 複製程式碼
forEach 使用說明
1、forEach
方法按升序為陣列中含有效值的每一項執行一次callback
函式,那些已刪除(使用delete
方法等情況)或者未初始化的項將被跳過(但不包括那些值為undefined
的項)(例如在稀疏陣列上)。
2、如果給forEach
傳遞了thisArg
引數,當呼叫時,它將被傳給callback
函式,作為它的this
值。否則,將會傳入window
作為它的this
值。callback
函式最終可觀察到this
值,這取決於 函式觀察到this
的常用規則。
關於 JavaScript 中的this
,我覺得太重要了,需要仔細研讀:
neveryu.github.io/2018/06/01/…
3、forEach
遍歷的範圍在第一次呼叫callback
前就會確定。呼叫forEach
後新增到陣列中的項不會被callback
訪問到。如果已經存在的值被改變,則傳遞給callback
的值是forEach
遍歷到他們那一刻的值。已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了(例如使用shift()
) ,之後的元素將被跳過。
4、forEach()
為每個陣列元素執行callback
函式;不像map()
或者reduce()
,它總是返回undefined
值,並且不可鏈式呼叫。典型用例是在一個鏈的最後執行副作用。
forEach 要點
1、沒有返回值
var arr1 = [1, 2, 3, 4, 5] var solt = arr1.forEach((v,i,t) => { console.log(v) }) console.log(solt)// undefined 複製程式碼
2、不能中止或跳出 forEach 迴圈
var arr1 = [1, 2, 3, 4, 5] // 使用break會報錯 arr1.forEach((v,i,arr) => { console.log(v) if(v === 3) { breck } }) // return false 也無效 arr1.forEach((v,i,arr) => { console.log(v) if(v === 3) { console.log('-----') return false } }) // 1 // 2 // 3 // ----- // 4 // 5 複製程式碼
3、使用箭頭函式,thisArg
引數會被忽略
var arr1 = [1, 2, 3] var arr2 = [7, 8, 9] arr1.forEach((v, i, arr) => { console.log(this) }) // window // window // window arr1.forEach((v, i, arr) => { console.log(this) }, arr2) // window // window // window 複製程式碼
4、forEach()
不會在迭代之前建立陣列的副本如果陣列在迭代時被修改了,則其他元素會被跳過
var words = ["one", "two", "three", "four"]; words.forEach(function(word) { console.log(word); if (word === "two") { words.shift(); } }); // one // two // four 複製程式碼
當到達包含值"two"
的項時,整個陣列的第一個項被移除了,這導致所有剩下的項上移一個位置。因為元素"four"
現在在陣列更前的位置,"three"
會被跳過。forEach()
不會在迭代之前建立陣列的副本。
5、對原陣列進行修改
var arr1 = [1, 2, 3] var arr2 = [7, 8, 9] arr1.forEach(function(v, i, arr) { console.log(this) arr[i] = v * 2 }, arr2) console.log(arr1) // (3) [7, 8, 9] // (3) [7, 8, 9] // (3) [7, 8, 9] // (3) [2, 4, 6] 複製程式碼
arr1 從 [1, 2, 3] 變成了 [2, 4, 6]函式內部this
值是arr2
map
map()
方法建立一個數組,其結果是該陣列中的每個元素都呼叫一個提供的函式後返回的結果
語法:
let new_array = arr.map(function(v, i, arr) { // Return element for new_array }[, thisArg]) 複製程式碼
返回值:
一個新陣列,每個元素都是回撥函式的結果 複製程式碼
map 使用說明
1、map
不修改呼叫它的原陣列本身(當然可以在 callback 執行時改變原陣列)。
2、如果thisArg
引數有值,則每次callback
函式被呼叫的時候,this
都會指向thisArg
引數上的這個物件。如果省略了thisArg
引數,或者賦值為null
或undefined
,則this
指向全域性物件 。
3、map
方法會給原陣列中的每個元素都按順序呼叫一次callback
函式。callback
每次執行後的返回值(包括undefined
)組合起來形成一個新陣列。callback
函式只會在有值的索引上被呼叫;那些從來沒被賦過值或者使用delete
刪除的索引則不會被呼叫。
4、使用map
方法處理陣列時,陣列元素的範圍是在callback
方法第一次呼叫之前就已經確定了。在map
方法執行的過程中:原陣列中新增加的元素將不會被callback
訪問到;若已經存在的元素被改變或刪除了,則它們的傳遞到callback
的值是map
方法遍歷到它們的那一時刻的值;而被刪除的元素將不會被訪問到。【
和forEach
一樣
】
map 要點
1、querySelectorAll
應用
var elems = document.querySelectorAll('select option:checked'); var values = Array.prototype.map.call(elems, function(obj) { return obj.value }); 複製程式碼
上面程式碼展示瞭如何去遍歷用querySelectorAl
得到的動態物件集合。在這裡,我們獲得了文件裡所有選中的選項,並將其列印。
map 使用技巧案例
通常情況下,map
方法中的callback
函式只需要接受一個引數,就是正在被遍歷的陣列元素本身。但這並不意味著map
只給callback
傳了一個引數。這個思維慣性可能會讓我們犯一個很容易犯的錯誤。
// 下面的語句返回什麼呢: ["1", "2", "3"].map(parseInt); // 你可能覺得會是 [1, 2, 3] // 但實際的結果是 [1, NaN, NaN] 複製程式碼
通常使用parseInt
時,只需要傳遞一個引數.
但實際上,parseInt
可以有兩個引數,第二個引數是進位制數.
可以通過語句alert(parseInt.length) === 2
來驗證.map
方法在呼叫callback
函式時,會給它傳遞三個引數:當前正在遍歷的元素,元素索引,原陣列本身.
第三個引數parseInt
會忽視,但第二個引數不會,也就是說:parseInt
把傳過來的索引值當成進位制數來使用. 從而返回了 NaN.
或者可以使用箭頭函式:
['1', '2', '3'].map( str => { parseInt(str) }) 複製程式碼
一個更簡單的方式:
['1', '2', '3'].map(Number);// [1, 2, 3] // 與 parseInt 不同,下面的結果會返回浮點數或指數: ['1.1', '2.2e2', '3e300'].map(Number);// [1.1, 220, 3e+300] 複製程式碼
filter
filter()
方法建立一個新陣列,其包含通過所提供函式實現的測試的所有元素
語法:
var new_array = arr.filter(callback[, thisArg]) 複製程式碼
filter 使用說明
1、filter
為陣列中的每個元素呼叫一次callback
函式,並利用所有使得callback
返回true
或等價於 true 的值 的元素建立一個新陣列。callback
只會在已經賦值的索引上被呼叫,對於那些已經被刪除或者從未被賦值的索引不會被呼叫。那些沒有通過callback
測試的元素會被跳過,不會被包含在新陣列中。
2、filter
不會改變原陣列,它返回過濾後的新陣列。
3、filter
遍歷的元素範圍在第一次呼叫callback
之前就已經確定了。在呼叫filter
之後被新增到陣列中的元素不會被filter
遍歷到。如果已經存在的元素被改變了,則他們傳入callback
的值是filter
遍歷到它們那一刻的值。被刪除或從來未被賦值的元素不會被遍歷到。