詳解vue數(shù)組遍歷方法forEach和map的原理解析和實(shí)際應(yīng)用
一、前言
forEach和map是數(shù)組的兩個(gè)方法,作用都是遍歷數(shù)組。在vue項(xiàng)目的處理數(shù)據(jù)中經(jīng)常會(huì)用到,這里介紹一下兩者的區(qū)別和具體用法示例。
二、代碼
1. 相同點(diǎn)
- 都是數(shù)組的方法
- 都用來(lái)遍歷數(shù)組
- 兩個(gè)函數(shù)都有4個(gè)參數(shù):匿名函數(shù)中可傳3個(gè)參數(shù)item(當(dāng)前項(xiàng)), index(當(dāng)前項(xiàng)的索引), arr(原數(shù)組),還有一個(gè)可選參數(shù)this
- 匿名函數(shù)中的this默認(rèn)是指向window的
- 對(duì)空數(shù)組不會(huì)調(diào)用回調(diào)函數(shù)
- 不會(huì)改變?cè)瓟?shù)組(某些情況下可改變)
2. forEach
(1) 沒(méi)有返回值。
var a = [1,2,3,4,5] var b = a.forEach((item) => { item = item * 2 }) console.log(b) // undefiined
(2) 可改變?cè)瓟?shù)組的情況
下面來(lái)看幾個(gè)例子:
var a = [1,2,3,4,5] a.forEach((item) => { item = item * 2 }) console.log(a) // [1,2,3,4,5]
這里原數(shù)組并沒(méi)有發(fā)生改變。
var a = [1,'1',{num:1},true] a.forEach((item, index, arr) => { item = 2 }) console.log(a) // [1,'1',{num:1},true]
這里修改item的值,依然沒(méi)有修改原數(shù)組。
var a = [1,'1',{num:1},true] a.forEach((item, index, arr) => { item.num = 2 item = 2 }) console.log(a) // [1,'1',{num:2},true]
當(dāng)修改數(shù)組中對(duì)象的某個(gè)屬性時(shí),發(fā)現(xiàn)屬性改變了。
為什么會(huì)這樣呢?
這里就要引入棧(stack)內(nèi)存和堆(heap)內(nèi)存的概念了,對(duì)于JS中的基本數(shù)據(jù)類(lèi)型,如String,Number,Boolean,Undefined,Null是存在于棧內(nèi)存中的,在棧內(nèi)存中儲(chǔ)存變量名及相應(yīng)的值。而Object,Array,Function存在于堆內(nèi)存中,在堆內(nèi)存中儲(chǔ)存變量名及引用位置。
在第一個(gè)例子中,為什么直接修改item無(wú)法修改原數(shù)組呢,因?yàn)閕tem的值并不是相應(yīng)的原數(shù)組中的值,而是重新建立的一個(gè)新變量,值和原數(shù)組相同。
在第二個(gè)例子中,數(shù)組中的對(duì)象的值也沒(méi)有改變,是因?yàn)樾聞?chuàng)建的變量和原數(shù)組中的對(duì)象雖然指向同一個(gè)地址,但改變的是新變量的值,即新對(duì)象的值為2,原數(shù)組中的對(duì)象還是{num:1}。
在第三個(gè)例子中,由于對(duì)象是引用類(lèi)型,新對(duì)象和舊對(duì)象指向的都是同一個(gè)地址,所以新對(duì)象把num變成了2,原數(shù)組中的對(duì)象也改變了。
var a = [1,2,3,4,5] a.forEach((item, index, arr) => { arr[index] = item * 2 }) console.log(a) // [2,4,6,8,10]
在回調(diào)函數(shù)里改變arr的值,原數(shù)組改變了。
這個(gè)例子和例三其實(shí)同理,參數(shù)中的arr也只是原數(shù)組的一個(gè)拷貝,如果修改數(shù)組中的某一項(xiàng)則原數(shù)組也改變因?yàn)橹赶蛲灰玫刂罚绻o參數(shù)arr賦其他值,則原數(shù)組不變。
其實(shí)想要知道參數(shù)中的item和arr是不是重新創(chuàng)建的變量,在回調(diào)函數(shù)中打印就知道了。
(3) vue中的應(yīng)用
在處理數(shù)據(jù)時(shí)我經(jīng)常用到這個(gè)方法,因?yàn)閿?shù)據(jù)的傳遞以json格式,經(jīng)常會(huì)收到數(shù)組中包含許多對(duì)象的數(shù)據(jù)。而后端傳給我的數(shù)據(jù)有時(shí)候需要處理,例如把時(shí)間戳格式化為正常時(shí)間,代碼如下:
// utils.js const formatTime = date => { var newDate = new Date(); newDate.setTime(date * 1000); const year = newDate.getFullYear() const month = newDate.getMonth() + 1 const day = newDate.getDate() const hour = newDate.getHours() const minute = newDate.getMinutes() const second = newDate.getSeconds() return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':') } const formatNumber = n => { n = n.toString() return n[1] ? n : '0' + n } export { formatTime }
// 得到的數(shù)據(jù)格式 [ {add_time: 1541495677, balance: 14, bn: "300708", cprice: "12.39"} ]
// index.vue import axios from 'axios' import { formatTime } from '@/lib/utils' export default { data() { dataList: [] }, methods: { getData() { axios.get('/user?ID=12345') .then(function (res) { if(res.code == 200) { res.data.forEach((item) => { item.add_time = formatTime(item.add_time) } this.dataList = res.data } }) .catch(function (err) { console.log(err); }); } } }
這時(shí)候原始數(shù)據(jù)的值也改變了,變成了格式化后的時(shí)間。
3. map
(1) 返回一個(gè)經(jīng)過(guò)處理后的新數(shù)組,但不改變?cè)瓟?shù)組的值。
var a = [1,2,3,4,5] var b = a.map((item) => { return item = item * 2 }) console.log(a) // [1,2,3,4,5] console.log(b) // [2,4,6,8,10]
(2) map中可改變?cè)瓟?shù)組的情況和原理與forEach相同
(3) vue中的應(yīng)用
有這樣一個(gè)需求,充值金額需要在整數(shù)的基礎(chǔ)上隨機(jī)減去100或加上100,這時(shí)我在原始的數(shù)據(jù)基礎(chǔ)上需要一個(gè)經(jīng)過(guò)處理的新數(shù)組。
export default { data() { moneyList: [1000,2000,5000,10000,20000,50000] }, computed: { moneyList_new() { return this.moneyList.map((item) => { const random = Math.random() > 0.5 ? 1 : -1; return Math.floor(Math.random()*100) * random + item; }) } } }
實(shí)際渲染處理過(guò)的數(shù)組就可以了~
三、結(jié)語(yǔ)
以上就是forEach和map的對(duì)比與實(shí)際應(yīng)用,代碼只是演示使用方法并非完全真實(shí)。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用Vuex實(shí)現(xiàn)一個(gè)筆記應(yīng)用的方法
這篇文章主要介紹了使用Vuex實(shí)現(xiàn)一個(gè)筆記應(yīng)用的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03微前端qiankun主應(yīng)用與子應(yīng)用之間的跳轉(zhuǎn)示例
這篇文章主要為大家介紹了微前端qiankun主應(yīng)用與子應(yīng)用之間的跳轉(zhuǎn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08vue如何解決watch和methods值執(zhí)行順序問(wèn)題
這篇文章主要介紹了vue如何解決watch和methods值執(zhí)行順序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08vue視頻播放插件vue-video-player的具體使用方法
這篇文章主要介紹了vue視頻播放插件vue-video-player的具體使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11vue init webpack myproject構(gòu)建項(xiàng)目 ip不能訪(fǎng)問(wèn)的解決方法
下面小編就為大家分享一篇vue init webpack myproject構(gòu)建項(xiàng)目 ip不能訪(fǎng)問(wèn)的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03解決vue3中使用echart報(bào)錯(cuò):Cannot read properties of&n
在Vue項(xiàng)目中使用Echarts進(jìn)行數(shù)據(jù)可視化是非常常見(jiàn)的需求,然而有時(shí)候在引入Echarts的過(guò)程中可能會(huì)遇到報(bào)錯(cuò),本文主要介紹了解決vue3中使用echart報(bào)錯(cuò):Cannot read properties of undefined (reading ‘type‘),感興趣的可以了解一下2024-01-01vue基于mint-ui實(shí)現(xiàn)城市選擇三級(jí)聯(lián)動(dòng)
這篇文章主要為大家詳細(xì)介紹了vue基于mint-ui實(shí)現(xiàn)城市選擇三級(jí)聯(lián)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04基于webpack4+vue-cli3項(xiàng)目實(shí)現(xiàn)換膚功能
這篇文章主要介紹了基于webpack4+vue-cli3項(xiàng)目的換膚功能,文中是通過(guò)scss+style-loader/useable做換膚功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07