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