Rest 和 Spread 操做符不單單能夠用於讓參數休息和擴展數組。javascript
下面針對 JavaScript 對象時使用 Rest 和 Spread 時的 7 個不爲人知的技巧。java
克隆一個對象,同時向(淺)克隆對象添加附加屬性。數組
在這個示例中,user 被克隆,password 屬性被添加到 userWithPass 中。函數
const user = { id: 100, name: 'Howard Moon'} const userWithPass = { ...user, password: 'Password!' } user //=> { id: 100, name: 'Howard Moon' } userWithPass //=> { id: 100, name: 'Howard Moon', password: 'Password!' }
將兩個對象合併到一個新對象中。this
將 Part1 和 Part2 合併到 user1中。spa
const part1 = { id: 100, name: 'Howard Moon' } const part2 = { id: 100, password: 'Password!' } const user1 = { ...part1, ...part2 } //=> { id: 100, name: 'Howard Moon', password: 'Password!' }
對象也可使用如下語法合併:rest
const partial = { id: 100, name: 'Howard Moon' } const user = { ...partial, id: 100, password: 'Password!' } user //=> { id: 100, name: 'Howard Moon', password: 'Password!' }
能夠結合使用解構 rest 運算符刪除屬性。 在這裏,password 被刪除 ,其他的屬性做爲 rest 返回。code
const noPassword = ({ password, ...rest }) => rest const user = { id: 100, name: 'Howard Moon', password: 'Password!' } noPassword(user) //=> { id: 100, name: 'Howard moon' }
函數接受一個 prop 做爲參數。使用計算對象屬性名稱,能夠從克隆中動態地刪除屬性。對象
const user1 = { id: 100, name: 'Howard Moon', password: 'Password!' } const removeProperty = prop => ({ [prop]: _, ...rest }) => rest // ---- ------ // \ / // dynamic destructuring const removePassword = removeProperty('password') const removeId = removeProperty('id') removePassword(user1) //=> { id: 100, name: 'Howard Moon' } removeId(user1) //=> { name: 'Howard Moon', password: 'Password!' }
有時性質並不按照咱們須要的順序排列。 使用一些技巧,咱們能夠將屬性推到列表的頂部,或者將它們移到底部。blog
若要將 id 移動到第一個位置,在擴展對象以前將 id: undefined
添加到新的 Object 最前面。
const user3 = { password: 'Password!', name: 'Naboo', id: 300 } const organize = object => ({ id: undefined, ...object }) // ------------- // / // move id to the first property organize(user3) //=> { id: 300, password: 'Password!', name: 'Naboo' }
若要將 password 移到最後一個屬性,請從對象中解構 password。而後在使用 Rest 操做符後從新設置 password 屬性。
const user3 = { password: 'Password!', name: 'Naboo', id: 300 } const organize = ({ password, ...object }) => ({ ...object, password }) // -------- // / // move password to last property organize(user3) //=> { name: 'Naboo', id: 300, password: 'Password!' }
默認屬性是僅當它們不包含在原始對象中時才設置的值。
在本例中,user2 不包含 quotes 屬性。 setdefaults 函數確保全部對象都設置了 quotes 屬性,不然它將被設置爲[]
。
當調用 setDefaults (user2)時,返回值將包含 quotes 屬性: []
。
在調用 setDefaults (user4)時,由於 user4 已經有了 quotes 屬性,因此不會修改該屬性。
const user2 = { id: 200, name: 'Vince Noir' } const user4 = { id: 400, name: 'Bollo', quotes: ["I've got a bad feeling about this..."] } const setDefaults = ({ quotes = [], ...object}) => ({ ...object, quotes }) setDefaults(user2) //=> { id: 200, name: 'Vince Noir', quotes: [] } setDefaults(user4) //=> { //=> id: 400, //=> name: 'Bollo', //=> quotes: ["I've got a bad feeling about this..."] //=> }
若是你但願默認值先出現而不是後出現,也能夠這樣寫:
const setDefaults = ({ ...object}) => ({ quotes: [], ...object })
經過結合上面的技術,能夠建立一個函數來重命名屬性。
假設有一些大寫 ID 的對象屬性名應該是小寫的 id。 首先從對象解構 ID 而後在對象 Spread 時將其做爲 id 添加回去。
const renamed = ({ ID, ...object }) => ({ id: ID, ...object }) const user = { ID: 500, name: "Bob Fossil" } renamed(user) //=> { id: 500, name: 'Bob Fossil' }
感謝 @vinialbano
指出你也能夠有條件地添加屬性。 在這個例子中,只有當 password 是真實的時候纔會添加 password!
const user = { id: 100, name: 'Howard Moon' } const password = 'Password!' const userWithPassword = { ...user, id: 100, ...(password && { password }) } userWithPassword //=> { id: 100, name: 'Howard Moon', password: 'Password!' }
我試着列出了一些不爲人知的 Spread 和 Rest 技巧,若是你知道任何我沒有列在這裏技巧,請在評論區裏讓每一個人都知道!若是你從中學到了新的東西,請在 Twitter 上和你的朋友分享,這真的頗有幫助!
請在這裏或者推特 @joelnet 關注我!