由于js中的數(shù)組是引用類型,所以可以利用類似指針的特性通過改變另一個(gè)變量去修改原始的值。我認(rèn)為這其實(shí)是js中的缺陷,所以我不喜歡利用這個(gè)"缺陷"去實(shí)現(xiàn)一些功能,在最近的一次code review中,同事指出了這個(gè)問題。所以我希望有更多朋友能給我一些建議。
下面就是簡(jiǎn)單的例子。
let arr = [{
a:1,
b:2,
}, {
a:3,
b:4,
}];
如果有以上數(shù)組,我需要將每一項(xiàng)的a改為3。大概有兩種寫法,一種是用forEach,另一種是用map來返回一個(gè)新數(shù)組(暫不考慮for循環(huán))。
forEach:
arr.forEach((item) => {
item.a = 3;
});
map:
arr = arr.map((item) => { // 有同事指出應(yīng)該聲明一個(gè)新變量來存儲(chǔ)map的結(jié)果,這個(gè)建議我認(rèn)為是對(duì)的。
item.a = 3;
return item;
});網(wǎng)絡(luò)上找了一點(diǎn)兒關(guān)于這個(gè)的一些比較和介紹,希望對(duì)你有所幫助!
原生JS forEach()和map()遍歷的異同點(diǎn)
共同點(diǎn):
1、都是循環(huán)遍歷數(shù)組中的每一項(xiàng)。
2、forEach()和map()里面每一次執(zhí)行匿名函數(shù)都支持3個(gè)參數(shù):數(shù)組中的當(dāng)前項(xiàng)item,當(dāng)前項(xiàng)的索引index,原始數(shù)組input。
3、匿名函數(shù)中的this都是指Window。
4、只能遍歷數(shù)組。
1.forEach()
沒有返回值
arr[].forEach(function(value,index,array){
//do something
})
參數(shù):value數(shù)組中的當(dāng)前項(xiàng), index當(dāng)前項(xiàng)的索引, array原始數(shù)組;
數(shù)組中有幾項(xiàng),那么傳遞進(jìn)去的匿名回調(diào)函數(shù)就需要執(zhí)行幾次;
理論上這個(gè)方法是沒有返回值的,僅僅是遍歷數(shù)組中的每一項(xiàng),不對(duì)原來數(shù)組進(jìn)行修改;但是可以自己通過數(shù)組的索引來修改原來的數(shù)組;
var ary = [12,23,24,42,1];
var res = ary.forEach(function (item,index,input) {
input[index] = item*10;
})
console.log(res);//--> undefined;
console.log(ary);//--> 通過數(shù)組索引改變了原數(shù)組;
2.map()
有返回值,可以return 出來。
arr[].map(function(value,index,array){
//do something
return XXX
})
參數(shù):value數(shù)組中的當(dāng)前項(xiàng),index當(dāng)前項(xiàng)的索引,array原始數(shù)組;
區(qū)別:map的回調(diào)函數(shù)中支持return返回值;return的是啥,相當(dāng)于把數(shù)組中的這一項(xiàng)變?yōu)樯叮ú⒉挥绊懺瓉淼臄?shù)組,只是相當(dāng)于把原數(shù)組克隆一份,把克隆的這一份的數(shù)組中的對(duì)應(yīng)項(xiàng)改變了);
var ary = [12,23,24,42,1];
var res = ary.map(function (item,index,input) {
return item*10;
})
console.log(res);//-->[120,230,240,420,10]; 原數(shù)組拷貝了一份,并進(jìn)行了修改
console.log(ary);//-->[12,23,24,42,1]; 原數(shù)組并未發(fā)生變化
兼容寫法:
不管是forEach還是map在IE6-8下都不兼容(不兼容的情況下在Array.prototype上沒有這兩個(gè)方法),那么需要我們自己封裝一個(gè)都兼容的方法,代碼如下:
/**
* forEach遍歷數(shù)組
* @param callback [function] 回調(diào)函數(shù);
* @param context [object] 上下文;
*/
Array.prototype.myForEach = function myForEach(callback,context){
context = context || window;
if('forEach' in Array.prototye) {
this.forEach(callback,context);
return;
}
//IE6-8下自己編寫回調(diào)函數(shù)執(zhí)行的邏輯
for(var i = 0,len = this.length; i < len;i++) {
callback && callback.call(context,this[i],i,this);
}
}
/**
* map遍歷數(shù)組
* @param callback [function] 回調(diào)函數(shù);
* @param context [object] 上下文;
*/
Array.prototype.myMap = function myMap(callback,context){
context = context || window;
if('map' in Array.prototye) {
return this.map(callback,context);
}
//IE6-8下自己編寫回調(diào)函數(shù)執(zhí)行的邏輯
var newAry = [];
for(var i = 0,len = this.length; i < len;i++) {
if(typeof callback === 'function') {
var val = callback.call(context,this[i],i,this);
newAry[newAry.length] = val;
}
}
return newAry;
}
希望我的回答對(duì)你有所幫助!
補(bǔ)充下,剛才沒仔細(xì)看題目。題目的map方法不夠“純粹”,實(shí)際上還是直接修改了每個(gè)item的屬性,要想不影響原有對(duì)象,應(yīng)該這么寫:
arr = arr.map((item) => { // 有同事指出應(yīng)該聲明一個(gè)新變量來存儲(chǔ)map的結(jié)果,這個(gè)建議我認(rèn)為是對(duì)的。
return {
...item,
a:3
}
});
==============
map方法體現(xiàn)的是數(shù)據(jù)不可變的思想。該思想認(rèn)為所有的數(shù)據(jù)都是不能改變的,只能通過生成新的數(shù)據(jù)來達(dá)到修改的目的,因此直接對(duì)數(shù)組元素或對(duì)象屬性進(jìn)行操作的行為都是不可取的。這種思想其實(shí)有很多好處,最直接的就是避免了數(shù)據(jù)的隱式修改。immutable.js是實(shí)現(xiàn)數(shù)據(jù)不可變的一個(gè)庫,可通過專屬的API對(duì)引用類型進(jìn)行操作,每次形成一個(gè)新的對(duì)象。
但具體到項(xiàng)目中還是要看團(tuán)隊(duì)的要求,都用或者都不用。單單局部使用是沒有效果的。
如果使用了React + Redux 的技術(shù)棧,是比較推薦使用的
另外有一點(diǎn),forEach和map還存在一個(gè)編程思想的區(qū)別,前者是命令式編程,后者是聲明式編程,如果項(xiàng)目的風(fēng)格是聲明式的,比如React,那么后者顯然更統(tǒng)一。
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問,美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。