這是第二篇關于 Javascript 實現(xiàn)方法的總結文章,主要是總結從 ES5 到 ES6 中的各種數(shù)組遍歷方式,以及使用這些方法可能會遇到的坑钦听。當然了鞭缭,剛開始總結的一定不會很全面,也希望有更多想法和問題的小伙伴可以大家一起交流且叁,文章也會一直完善下去,雖然不一定會有人看,哈哈救赐,那開始吧!
Javascript 有很多數(shù)組遍歷的方法,我們先從傳統(tǒng)的遍歷方法開始经磅,然后再引入ES6
的新方法:
1. while
傳統(tǒng)方法while
理解起來很簡單泌绣,給個index
然后每次讓index ++
就ok了。然后我們引入了一個新的概念预厌,就是ES6
中的新語法...
阿迈,它可以用于但不僅限于數(shù)組和對象的的擴展和解構,從一定程度講轧叽,把它用好了在某種程度上就基本可以拋棄ES5
里面像concat
苗沧、slice
等等的數(shù)組拼接方法了(只是說基本,目前還不敢全扔)炭晒。
關于ES6
的用法已經(jīng)基本整理好了待逞,在未來兩三個星期會陸續(xù)發(fā),希望到時候可以關注网严。這里扔一個權威的傳送門识樱,阮一峰老師的《ECMAScript 6入門》:http://es6.ruanyifeng.com/
function whileLooping(...args) {
let index = 0
while(index < args.length){
console.log(args[index])
index ++
}
}
const flag = [1, 2, 3, 4]
whileLooping('java', 'python', 'c', 'c++', 'ruby')
// java python c c++ ruby
whileLooping('java', 'python', 'c', 'c++', 'ruby', flag)
// java python c c++ ruby [1, 2, 3, 4]
很簡單,主要是為了做一個關于...
語法的引子震束,讓大家多使用更便捷的方法(雖然這里這么寫好像有些雞肋)怜庸。
2. for(傳統(tǒng)方法里用的最多的)
這個我覺得不管是寫什么的都比我熟,所以先象征性地扔一波看起來雞肋又尷尬的代碼:
function forLooping(array = [a = 10, b = 20, ...args], nothing = 20){
for(let i = 0; i < array.length; i++) {
console.log(array[i])
}
console.log(nothing)
}
forLooping([1, 2, 3, 4, 5])
// 1 2 3 4 5 20
forLooping([1, 2, 3, 4, 5], 10)
// 1 2 3 4 5 10
雖然這里涉及了ES6
里的默認參數(shù)值以及...
的另一種用法垢村,但看起來都容易理解割疾,就不多嗶嗶。接下來要分享的是一個我曾經(jīng)在用for
循環(huán)遇到的一個坑嘉栓,關于作用域的宏榕。
大家可以嘗試把let
變成var
,看看輸出結果有什么變化嗎侵佃?并沒有担扑。
但是在接下來這段代碼里好像就不太一樣了:
const array = []
for (var i = 0; i < 5; i++) {
array.push(function() {
console.log(i)
})
}
array[0]() // 5
array[1]() // 5
array[2]() // 5
array[3]() // 5
array[4]() // 5
console.log(array) // [ [Function], [Function], [Function], [Function], [Function] ]
明明push
到數(shù)組里的看起來都是不一樣的值,可是最后一跑就發(fā)現(xiàn)輸出了沒有一個值是對的趣钱。這是在var
聲明的時候涌献,被引用的外部作用域中只有一個i
,而不是為每次迭代的函數(shù)都有一個i
被引用首有。如果你用let
聲明i
燕垃,輸出的值就會是0 1 2 3 4
。這關系到var
和let
的區(qū)別井联,上面給的傳送門里有介紹到卜壕,而我之后的ES6
系列也會解釋到,這里也不多嗶嗶了烙常。
還有一件事就是轴捎,在某些博客上有人說const
是用來聲明常量的鹤盒,可我們這里的array
還能改變,這是因為用const
聲明值類型變量之后不能繼續(xù)賦值侦副,但是聲明的引用類型變量還是可以被改變的侦锯。
3. forEach
這個是新方法里最基礎的一個,唯一要注意的是IE 9
以下瀏覽器不兼容秦驯。用的時候要向里面扔三個參數(shù):
- currentValue(必需):當前元素尺碰;
- index(可選):當前元素索引值;
- arr(可選):當前元素所屬的數(shù)組對象译隘。
function forEachLooping(...args) {
args.forEach((current_value, index, arr) => {
console.log(current_value, index, arr)
})
}
forEachLooping('java', 'python', 'c', 'c++', 'ruby')
// java 0 [ 'java', 'python', 'c', 'c++', 'ruby' ]
// python 1 [ 'java', 'python', 'c', 'c++', 'ruby' ]
// c 2 [ 'java', 'python', 'c', 'c++', 'ruby' ]
// c++ 3 [ 'java', 'python', 'c', 'c++', 'ruby' ]
// ruby 4 [ 'java', 'python', 'c', 'c++', 'ruby' ]
箭頭函數(shù)=>
用法值得關注亲桥,很好用,會在ES6
系列里面具體介紹到固耘。其它暫時沒發(fā)現(xiàn)什么值得特別提的點题篷,如果有小伙伴遇到這個東西的坑,希望可以跟我說一下厅目,我們一起進步哈番枚!
4. map
這里的map
不是地圖
的意思,而是指映射
璧瞬,很好理解,就是原數(shù)組被映射
成新的數(shù)組渐夸。在forEach
方法中嗤锉,并不會返回一個新的數(shù)組,而map
則是對數(shù)組的每個元素使用一個函數(shù)墓塌,然后返回一個全新的數(shù)組瘟忱。
function mapLooping(information) {
const formatInfo = information.map(info => {
return `姓名:${info.name},年齡:${info.age}`
})
console.log(formatInfo)
}
const information = [
{name: 'zixiang.xiao', age: 22},
{name: 'tong.li', age: 22},
{name: 'meimei.han', age: 30}
]
mapLooping(information)
// [ '姓名:zixiang.xiao苫幢,年齡:22',
// '姓名:tong.li访诱,年齡:22',
// '姓名:meimei.han,年齡:30' ]
上面的代碼也引入了ES6
模板字符串的概念韩肝,書寫起來相當方便触菜,沒什么特別的概念,有興趣可以去了解一下哀峻。
關于map
的兼容性涡相,它不兼容IE 9
以下版本的瀏覽器,如果非要在IE 6-8
之間使用的話剩蟀,也可以在Array.prototype
里面進行擴展:
if (typeof Array.prototype.map != "function") {
Array.prototype.map = function (fn, context) {
var arr = []
if (typeof fn === "function") {
for (var k = 0, length = this.length; k < length; k++) {
arr.push(fn.call(context, this[k], k, this))
}
}
return arr
}
}
5. reduce
從某種程度上說reduce
像是一個累加器催蝗,它會在數(shù)組中從左到右依次遍歷,最終返回一個經(jīng)過函數(shù)處理后的累積值育特。
function reduceLooping(...args) {
const array_sum = args.reduce((x, y) => {
return x + y
}, 10)
console.log(`初始值為10的array_sum累加之后結果為:${array_sum}`)
}
reduceLooping(1, 2, 3, 4, 5)
// 初始值為10的array_sum累加之后結果為:25
還有一個值得關注的點丙号,如果數(shù)組處理之后需要返回一個累積值的時候,推薦使用reduce
,從一個最直接的角度來說犬缨,據(jù)統(tǒng)計reduce
的運算速度比for
快幾十倍喳魏。同樣的,reduce
只兼容IE 9
及其以上的瀏覽器遍尺。
6. filter
跟名字一樣截酷,filter
方法就是用來對一個數(shù)組進行過濾的。和之前的方法不一樣的一點在于乾戏,filter
的callback
函數(shù)返回的是一個Boolean
值迂苛。
function filterLooping(array) {
const after = array.filter(name => name.indexOf('D') >= 0)
console.log(after)
}
const name = ['Durant','James','Bryant','Duncan','Curry']
filterLooping(name)
// [ 'Durant', 'Duncan' ]
filter
只兼容IE 9
及其以上的瀏覽器。
7. every
關于every
方法鼓择,用于檢測數(shù)組所有元素是否都符合指定條件,使用指定函數(shù)檢測數(shù)組中的所有元素:
- 如果數(shù)組中檢測到有一個元素不滿足三幻,則整個表達式返回
false
,且剩余的元素不會再進行檢測呐能; - 如果所有元素都滿足條件念搬,則返回
true
。
function everyLooping(array) {
let truth = array.every(user => user.indexOf('cool') >= 0)
if(truth) {
console.log('都很帥摆出!');
}else {
console.log('并不是所有人都很帥朗徊!')
}
}
const user = ['zixiang.xiao, cool','lei.li, 9','meimei.han, 9','mou.liu, pdd','benwei.lu, ugly']
everyLooping(user)
// 并不是所有人都很帥!
可解釋的不多偎漫,every
只兼容IE 9
及其以上的瀏覽器爷恳。希望看完代碼你不會覺得我厚顏無恥,就算你真這樣覺得也沒有什么用象踊!
8. some
some
的用法和every
其實差不多温亲,只不過some
的含義是判斷一個數(shù)組上的元素是否至少有一個符合某種條件, 方法會依次執(zhí)行數(shù)組的每個元素:
- 如果有一個元素滿足條件杯矩,則表達式返回
true
, 剩余的元素不會再執(zhí)行檢測栈虚; - 如果沒有滿足條件的元素,則返回
false
史隆。
function someLooping(array) {
let truth = array.some(user => user.indexOf('benwei.lu') >= 0)
if(truth) {
console.log('有人長得丑魂务!');
}else {
console.log('并沒有特別丑的人!')
}
}
const user = ['zixiang.xiao, cool','lei.li, 9','meimei.han, 9','mou.liu, pdd','benwei.lu, ugly']
someLooping(user)
// 有人長得丑泌射!
這個代碼看完我相信你會覺得我說的真對头镊!
總結
其實每一種方法都有它特定的場景可以作為一個優(yōu)秀的方案使用,作為一個前端小菜雞魄幕,我也會多去嘗試這些東西的使用相艇,在一定的累積之后會繼續(xù)寫它們的應用。關于低版本瀏覽器不兼容的問題纯陨,之后我會在原文章上邊添加關于低版本瀏覽器的兼容方法坛芽,不過目前我只能做到兼容到IE6
留储,我相信也沒多少人用更低的版本了,畢竟長得帥的人用瀏覽器都是與時俱進的咙轩!
最后最后获讳,如果你覺得我寫的還行的話,就快給我點贊并且關注我吧活喊!我會繼續(xù)努力的丐膝!謝謝各位大佬!