2 回答

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超6個(gè)贊
您根本無(wú)法使用本機(jī)Map,因?yàn)樗鼉H提供命令式接口。
您可以使用開(kāi)源庫(kù),例如流行的 ImmutableJS。
或者您可以編寫(xiě)自己的持久(不可變)數(shù)據(jù)結(jié)構(gòu)?;疽笫悄臄?shù)據(jù)結(jié)構(gòu)提供的操作不會(huì)修改輸入。相反,每個(gè)操作都會(huì)返回一個(gè)新的數(shù)據(jù)結(jié)構(gòu) -
const PersistentMap =
{ create: () =>
({})
, set: (t = {}, key, value) =>
({ ...t, [key]: value }) // <-- immutable operation
}
我們首先看一張empty地圖,一個(gè)set操作的結(jié)果,然后確保empty地圖沒(méi)有被修改——
const empty =
PersistentMap.create()
console.log
( empty
, PersistentMap.set(empty, "hello", "world")
, empty
)
// {}
// { hello: "world" }
// {}
現(xiàn)在讓我們看一個(gè)新的中間狀態(tài),m1。每次我們看到set返回一個(gè)新的持久映射并且不修改輸入 -
const m1 =
PersistentMap.set(empty, "hello", "earth")
console.log
( m1
, PersistentMap.set(m1, "stay", "inside")
, m1
)
// { hello: "earth" }
// { hello: "earth", stay: "inside" }
// { hello: "earth" }
現(xiàn)在回答你的問(wèn)題,我們可以添加一個(gè)push操作到我們的PersitentMap- 我們只需要確保我們不修改輸入。這是一種可能的實(shí)現(xiàn)-
const PersistentMap =
{ // ...
, push: (t = {}, key, value) =>
PersistentMap.set // <-- immutable operation
( t
, key
, Array.isArray(t[key])
? [ ...t[key], value ] // <-- immutable operation
: [ value ]
)
}
我們push在下面看到行動(dòng)。請(qǐng)注意,m2也不會(huì)empty因此而改變 -
const m2 =
PersistentMap.push(empty, "fruits", "apple")
console.log
( m2
, PersistentMap.push(m2, "fruits", "peach")
, m2
, empty
)
// { fruits: [ "apple" ] }
// { fruits: [ "apple", "peach" ] }
// { fruits: [ "apple" ] }
// {}
展開(kāi)下面的代碼段以在您自己的瀏覽器中驗(yàn)證結(jié)果
const PersistentMap =
{ create: () =>
({})
, set: (t = {}, key, value) =>
({ ...t, [key]: value })
, push: (t = {}, key, value) =>
PersistentMap.set
( t
, key
, Array.isArray(t[key])
? [ ...t[key], value ]
: [ value ]
)
}
const empty =
PersistentMap.create()
console.log
( empty
, PersistentMap.set(empty, "hello", "world")
, empty
)
// {}
// { hello: "world" }
// {}
const m1 =
PersistentMap.set(empty, "hello", "earth")
console.log
( m1
, PersistentMap.set(m1, "stay", "inside")
, m1
)
// { hello: "earth" }
// { hello: "earth", stay: "inside" }
// { hello: "earth" }
const m2 =
PersistentMap.push(empty, "fruits", "apple")
console.log
( m2
, PersistentMap.push(m2, "fruits", "peach")
, m2
, empty
)
// { fruits: [ "apple" ] }
// { fruits: [ "apple", "peach" ] }
// { fruits: [ "apple" ] }
// {}

TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超9個(gè)贊
我認(rèn)為這取決于你想要達(dá)到的目標(biāo)。如果您希望您的代碼是可測(cè)試的,F(xiàn)P 并不總是意味著只需要編寫(xiě)函數(shù),您仍然可以使用類,但是如果您有一段復(fù)雜的代碼要單獨(dú)測(cè)試,您可以導(dǎo)出該代碼段進(jìn)行測(cè)試,并且它看起來(lái)像這樣:
// types.ts
type FooDis = Record<string, object[]>;
// addBarToFoos.ts
export const addBarToFoos = (foos: FooDis) => (key: string, bar: object): FooDis {
foos = {
...foos,
[key]: [
...foos[key],
bar
]
};
return foos;
}
// FooClass.ts
export class FooClass {
private foos: FooDis = {};
addBar(key: string, bar: object) {
this.foos = addBarToFoos(this.foos)(key, bar);
}
}
這樣,“復(fù)雜”方法可以在沒(méi)有外部依賴的情況下單獨(dú)測(cè)試,并且您有一個(gè)使用該方法的實(shí)現(xiàn)。
添加回答
舉報(bào)