初學者常直覺將 Object 如 String 以 + 合併,但 Object 須以特殊方式才能合併。
Version
macOS Mojave 10.14.5
VS Code 1.37.0
Quokka 1.0.240
ECMAScript 2015
Ramda 0.26.1
Plus Operator
let obj1 = { firstName: 'Sam' };
let obj2 = { lastName: 'Xiao' };
let obj3 = obj1 + obj2; // ?
直覺會使用 + plus operator。

回傳為不預期結果,因此不能使用 +。
Object.assign()
import { equals } from 'ramda';
let obj1 = { firstName: 'Sam' };
let obj2 = { lastName: 'Xiao' };
let obj3 = Object.assign({}, obj1, obj2); // ?
在 ES5 若要 merge object,必須使用 Object.assign()。
Object.assign(target, …sources)
將 source object merge 到 target object
target:target object
...sources:source object,可包含多個 object
Object.assign() 原本是 merge object,所以第一個 argument 為 target object,若 target object 為 {},其行為剛好等於 clone object。
其中 sources 前有 ...,表示可接受無限 source object。

Spread Operator
let obj1 = { firstName: 'Sam' };
let obj2 = { lastName: 'Xiao'};
let obj3 = {...obj1, ...obj2 }; // ?
ES6 可在 {} 內使用 ... 將 property 展開,中間加上 , 即可合併 object。

Ramda
import { merge, mergeRight } from 'ramda';
let obj1 = { firstName: 'Sam' };
let obj2 = { lastName: 'Xiao'};
let obj3 = merge(obj1, obj2); // ?
let obj4 = mergeRight(obj1, obj2); // ?
Ramda 也提供了 merge() 與 mergeRight() 合併 object,功能與 Object.assign() 一樣。
merge()
{k: v} -> {k: v} -> {k: v}
將兩個 object 合併,若 property 相同,則第二個 object 的 property 會蓋掉第一個 object
{k: v}:第一個 object
{k: v}:第二個 object
{k: v}:回傳合併後的 object
mergeRight()
{k: v} -> {k: v} -> {k: v}將兩個 object 合併,若 property 相同,則第二個 object 的 property 蓋掉第一個 object
{k: v}:第一個 object
{k: v}:第二個 object
{k: v}:回傳合併後的 object
事實上
merge()與mergeRight()底層也是由Object.assign()實作,也因為merge()與mergeRight()功能完全相同,但merge()已經被官網列為deprecated,建議使用mergeRight()取代merge()

Conclusion
- clone 還有分 shallow clone 與 deep clone,但 merge 都只有 shallow merge 而以,因此 Ramda 的
merge()並沒有太大優勢,只剩下 function 名稱可讀性較佳與 curried function 而已
Reference
MDN, object.assign()
MDN, Spread syntax
Ramda, merge()
Ramda, mergeRight()