Js通過deepMerge實(shí)現(xiàn)默認(rèn)配置和自定義配置的合并
在做自定義配置文件時(shí),為了簡化操作掺喻,通常會采用默認(rèn)配置尼酿,再在此基礎(chǔ)上合并(Merge)用戶自定義配置,且用戶自定義配置會覆蓋對應(yīng)的默認(rèn)配置拯辙,經(jīng)測試發(fā)現(xiàn),使用 deepMerge 庫可以輕松靈活實(shí)現(xiàn)颜价。<font color="red">提示:請確保您的計(jì)算機(jī)安裝了 NodeJS 運(yùn)行環(huán)境涯保。</font>
1 實(shí)現(xiàn)目標(biāo)
通過 defaultConfig 對象默認(rèn)配置值,可以確保在沒有進(jìn)行用戶配置的情況下周伦,系統(tǒng)按照默認(rèn)配置運(yùn)行夕春,使應(yīng)用能夠“開箱即用”,提升用戶體驗(yàn)专挪;當(dāng)用戶需要滿足各種不同需要時(shí)及志,可以通過 userConfig 對象進(jìn)行用戶功能配置,滿足靈活應(yīng)用的需要狈蚤。
2 關(guān)于 deepMerge
2.1 deepMerge 庫相關(guān)介紹
deepMerge 庫可以通過 npm 安裝困肩。
安裝包的鏈接為:https://www.npmjs.com/package/deepmerge,
github 倉庫地址為:https://github.com/TehShrike/deepmerge脆侮。
2.2 deepMerge 的引入
可以在 Shell 里運(yùn)行下面的命令安裝:
npm install deepmerge
安裝完成后可通過下面的 js 代碼引入:
const merge = require('deepmerge')
2.3 deepMerge 基本用法
merge(x, y, [options])
深度合并兩個(gè)對象 x 和 y 锌畸,返回一個(gè)新的合并后的對象,元素來自 x 和 y 靖避, x 和 y 都不會發(fā)生改變潭枣。
注意:上面的 options 是可選項(xiàng),默認(rèn)情況下(即沒有輸入 options 時(shí))幻捏,兩個(gè)對象的數(shù)組會連接起來盆犁。
- 下面的代碼測試 deepMerge 庫默認(rèn)配置下的效果:
const merge = require('deepmerge')
// 下面定義數(shù)組覆蓋選項(xiàng),當(dāng)要實(shí)現(xiàn)數(shù)組覆蓋的時(shí)候篡九,可以在 merge 時(shí)使用該選項(xiàng)
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray
let x = {
a: {
a1: 'A1',
a2: 'A2'
},
b: {
b1: ['B1']
}
}
let y = {
a: {
a1: 'A1-new',
a3: 'created'
},
b: {
b1: ['B2']
}
}
let z1 = merge(x, y)
console.log('下面采用默認(rèn)選項(xiàng)的 merge 結(jié)果:')
console.log(z1)
let z2 = merge(x, y, { arrayMerge: overwriteMerge })
console.log('下面采用數(shù)組覆蓋選項(xiàng)的 merge 結(jié)果:')
console.log(z2)
- 得到對象 z 的結(jié)果打印如下:
//下面采用默認(rèn)選項(xiàng)的 merge 結(jié)果:
{
a: {
a1: 'A1-new',
a2: 'A2',
a3: 'created'
},
b: {
b1: ['B1', 'B2']
}
}
//下面采用數(shù)組覆蓋選項(xiàng)的 merge 結(jié)果:
{
a: {
a1: 'A1-new',
a2: 'A2',
a3: 'created'
},
b: {
b1: ['B2']
}
}
-
結(jié)果解析
1)值類型會被覆蓋
值類型為:字符串(string)谐岁、數(shù)值(number)、布爾值(boolean)、null伊佃、undefined窜司,當(dāng) x,y 對象中有相同的key 對應(yīng)的數(shù)據(jù)類型為值類型時(shí)航揉,值會被覆蓋塞祈,如:
x.a.a1 = 'A1'
y.a.a1 = 'A1-new'
merge的結(jié)果就是 'A1-new' 會覆蓋 'A1',z.a.a1 = 'A1-new'
2)“左側(cè)”內(nèi)容會保留
如某鍵在 x (左側(cè))中存在帅涂,在 y(右側(cè)) 中不存在议薪,則 x 的內(nèi)容會被保留,如:x.a.a2 = 'A2', y.a.a2不存在媳友,所以:z.a.a2 = 'A2'( x.a.a2 被保留在 z.a.a2 中)
3)默認(rèn)配置下引用類型:對象(Object)斯议、數(shù)組(Array)默認(rèn)會合并
如對象屬性:x.a.a3 不存在,y.a.a3 = 'created'庆锦,y.a.a3的內(nèi)容就被合并到 z 中捅位,z.a.a3 = 'created'
如數(shù)組元素:x.b.b1 = [ 'B1' ],y.b.b1 = [ 'B2' ]搂抒,此兩項(xiàng)內(nèi)容被合并到 z 中,z.b.b1 = [ 'B1', 'B2' ]
4)配置數(shù)組屬性覆蓋
當(dāng)配置數(shù)組屬性覆蓋時(shí)尿扯,在 merge 后的對象 z 里求晶,z.b.b1 的值取 y.b.b1 的值,即z.b.b1= [ 'B2' ]3 應(yīng)用測試
創(chuàng)建 test-merge.js 文件衷笋,編寫代碼如下
const merge = require('deepmerge')
下面定義數(shù)組覆蓋選項(xiàng)芳杏,當(dāng)要實(shí)現(xiàn)數(shù)組覆蓋的時(shí)候,可以在merge時(shí)使用該選項(xiàng)
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray
3.1 defaultConfig 的對象定義
在 test-merge.js 文件里定義 defaultConfig 對象:
const defaultConfig={ title: '模擬考試', students: 50, subjects: 2, subjectList: [ '語文', '數(shù)學(xué)' ] }
3.2 userConfig 的對象定義
在 test-merge.js 文件里定義 userConfig 對象:
const userConfig={ title: 'xx年度會考', students: 60, subjectList: [ '地理', '生物' ] }
3.3 deepMerge 合并生成 finalConfig 對象
一般作為配置文件的合并辟宗,數(shù)組一般會使用覆蓋模式爵赵,繼續(xù)編寫代碼:
const finalConfig = merge(defaultConfig, userConfig, { arrayMerge: overwriteMerge }) console.log(finalConfig)
運(yùn)行后得到的結(jié)果為
{ title: 'xx年度會考', students: 60, subjects: 2, subjectsList: [ '地理', '生物' ] }
完美實(shí)現(xiàn)默認(rèn)配置和自定義配置的合并。