原文地址:codeburst.io/writing-jav…
作者:Shivek Khurana
簡介:本文是一份編寫優雅、簡潔和函式式ES6程式碼的快捷清單。
現如今JavaScript有許多問題,但是詞法並不是其中之一。不管是三元運算子,還是map/reduce等ES6方法,亦或是擴充套件運算子(…)都是非常強大的工具。
除了能夠保證可讀性以及準確性,這些方法還有助於實現不可變性,因為這些方法會返回新的資料,而處理前的原始資料並不會被修改。這樣的處理風格很適合redux以及Fractal。
話不多說,讓我們開始吧。
一個簡單的reduce實踐
當你想要將多個資料放進一個例項中時,你可以使用一個reducer。
const posts = [
{id: 1, upVotes: 2},
{id: 2, upVotes: 89},
{id: 3, upVotes: 1}
];
const totalUpvotes = posts.reduce((totalUpvotes, currentPost) =>
totalUpvotes + currentPost.upVotes, //reducer函式
0 // 初始化投票數為0
);
console.log(totalUpvotes)//輸出投票總數:92
複製程式碼
傳給reduce的第一個引數函式還可以增加2個引數:
- 第三個引數:每個元素在原資料結構中的位置,比如陣列下標。
- 第四個引數:呼叫reduce方法的資料集合,比如例子中的posts。
所以,一個reducer的完全體應該是下面這樣的:
collection.reduce(
(accumulator, currentElement, currentIndex, collectionCopy) =>
{/*function body*/},
initialAccumulatorValue
);
複製程式碼
一個簡單的map實踐
map方法的作用在於處理流式資料,比如陣列。我們可以把它想象成所有元素都要經過的一個轉換器。
const integers = [1, 2, 3, 4, 6, 7];
const twoXIntegers = integers.map(i => i*2);
// twoXIntegers現在是 [2, 4, 6, 8, 12, 14],而integers不發生變化。
複製程式碼
一個簡單的find實踐
find返回陣列或類似結構中滿足條件的第一個元素。
const posts = [
{id: 1, title: `Title 1`},
{id: 2, title: `Title 2`}
];
// 找出id為1的posts
const title = posts.find(p => p.id === 1).title;
複製程式碼
一個簡單的filter實踐
filter方法可以篩除陣列和類似結構中不滿足條件的元素,並返回滿足條件的元素組成的陣列。
const integers = [1, 2, 3, 4, 6, 7];
const evenIntegers = integers.filter(i => i%2 === 0);
// evenIntegers的值為[2, 4, 6]
複製程式碼
向陣列中新增元素
如果你要建立一個無限滾動的ui元件(比如本文後面提到的例子),可以使用擴充套件運算子這個非常有用的詞法。
const books = [`Positioning by Trout`, `War by Green`];
const newBooks = [...books, `HWFIF by Carnegie`];
// newBooks are now [`Positioning by Trout`, `War by Green`, `HWFIF // by Carnegie`]
複製程式碼
為一個陣列建立檢視
如果需要實現使用者從購物車中刪除物品,但是又不想破壞原來的購物車列表,可以使用filter方法。
const myId = 6;
const userIds = [1, 5, 7, 3, 6];
const allButMe = userIds.filter(id => id !== myId);
// allButMe is [1, 5, 7, 3]
複製程式碼
譯者注:這裡我猜測作者是不想修改原來的陣列所以使用的filter,但是不能理解為什麼要舉購物車的例子。
向物件陣列新增新元素
const books = [];
const newBook = {title: `Alice in wonderland`, id: 1};
const updatedBooks = [...books, newBook];
//updatedBooks的值為[{title: `Alice in wonderland`, id: 1}]
複製程式碼
books這個變數我們沒有給出定義,但是不要緊,我們使用了擴充套件運算子,它並不會因此失效。
為物件新增一組鍵值對
const user = {name: `Shivek Khurana`};
const updatedUser = {...user, age: 23};
//updatedUser的值為:{name: `Shivek Khurana`, age: 23}
複製程式碼
使用變數作為鍵名為物件新增鍵值對
const dynamicKey = `wearsSpectacles`;
const user = {name: `Shivek Khurana`};
const updatedUser = {...user, [dynamicKey]: true};
// updatedUser is {name: `Shivek Khurana`, wearsSpectacles: true}
複製程式碼
修改陣列中滿足條件的元素物件
const posts = [
{id: 1, title: `Title 1`},
{id: 2, title: `Title 2`}
];
const updatedPosts = posts.map(p => p.id !== 1 ?
p : {...p, title: `Updated Title 1`}
);
/*
updatedPosts is now
[
{id: 1, title: `Updated Title 1`},
{id: 2, title: `Title 2`}
];
*/
複製程式碼
找出陣列中滿足條件的元素
const posts = [
{id: 1, title: `Title 1`},
{id: 2, title: `Title 2`}
];
const postInQuestion = posts.find(p => p.id === 2);
// postInQuestion now holds {id: 2, title: `Title 2`}
複製程式碼
譯者注:奇怪啊,這不就是之前find的簡單實踐嗎?
刪除目標物件的一組屬性
const user = {name: `Shivek Khurana`, age: 23, password: `SantaCl@use`};
const userWithoutPassword = Object.keys(user)
.filter(key => key !== `password`)
.map(key => {[key]: user[key]})
.reduce((accumulator, current) =>
({...accumulator, ...current}),
{}
)
;
// userWithoutPassword becomes {name: `Shivek Khurana`, age: 23}
複製程式碼
感謝Kevin Bradley提供了一個更優雅的方法:
const user = {name: `Shivek Khurana`, age: 23, password: `SantaCl@use`};
const userWithoutPassword = (({name, age}) => ({name, age}))(user);
複製程式碼
他還表示這個方法在物件屬性更少時也能發揮作用。
將物件轉化成請求串
你也許幾乎遇不到這個需求,但是有時候在別的地方會給你一點啟發。
const params = {color: `red`, minPrice: 8000, maxPrice: 10000};
const query = `?` + Object.keys(params)
.map(k =>
encodeURIComponent(k) + `=` + encodeURIComponent(params[k])
)
.join(`&`)
;
// encodeURIComponent將對特殊字元進行編碼。
// query is now "color=red&minPrice=8000&maxPrice=10000"
複製程式碼
獲取陣列中某一物件的下標
const posts = [
{id: 13, title: `Title 221`},
{id: 5, title: `Title 102`},
{id: 131, title: `Title 18`},
{id: 55, title: `Title 234`}
];
// 找到id為131的元素
const requiredIndex = posts.map(p => p.id).indexOf(131);
複製程式碼
譯者注:這裡我覺得方法很繁瑣。可以使用findIndex方法:
const requiredIndex = posts.findIndex(obj=>obj.id===131);
,同樣能獲取到下標值2。
作者總結
有了這些強大的方法,我希望你的程式碼會變得越來越穩定和一絲不苟。當你的團隊中有一個新的開發者加入時,可以向他推薦這篇文章,讓他了解以前不知道的祕密。
這個翻譯專案才開始,以後會翻譯越來越多的作品。我會努力堅持的。
專案地址:github.com/WhiteYin/tr…