You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Immutable JS深度合并异常:对象被完全覆盖而非部分合并

解决Immutable JS 3.8.1深度合并大型Map时的嵌套属性覆盖问题

我之前碰到过一模一样的坑,这其实是你创建Immutable结构的方式不对导致的——当你用Immutable.Map()把普通对象转成Map时,嵌套的子对象并没有被转换成Immutable Map,还是原生的JS对象。而Immutable 3.8.1的mergeDeep对非Immutable的嵌套值会直接替换,根本不会去深度合并里面的属性。

问题根源拆解

你看这段代码:

const map2 = Immutable.Map(obj2);

这里map2里的"foo.bar"对应的是一个普通JS对象,不是Immutable Map。当你用mergeDeep合并map1时,map1里同键对应的普通对象会直接覆盖掉map2里的值,自然就丢失了key1、key2这些属性。

正确解决方案

要让mergeDeep按预期合并嵌套属性,你需要把整个对象递归转换成Immutable结构,用Immutable.fromJS()代替Immutable.Map()就好:

const obj1 = { "foo.bar": { valid: ['baz'] } }
const obj2 = { "foo.bar": { key1: 'abc', key2: [1, 2, 3], valid: ['baz', 'bar', 'foo'] } }

// 用fromJS递归转成Immutable嵌套结构
const immutableObj2 = Immutable.fromJS(obj2);
const immutableObj1 = Immutable.fromJS(obj1);

const mergedResult = immutableObj2.mergeDeep(immutableObj1);
console.log(mergedResult.toJS());

运行后就能得到你想要的结果:

{ "foo.bar": { key1: 'abc', key2: [1, 2, 3], valid: ['baz'] } }

原理说明

Immutable.fromJS()会递归处理整个对象:把普通JS对象转成Immutable Map,数组转成Immutable List。这样mergeDeep处理这些嵌套的Immutable结构时,会逐层递归合并属性:

  • 顶层的"foo.bar"键会触发嵌套Map的合并
  • 嵌套Map里的valid(已转成Immutable List)会被合并替换,而key1、key2这类未被覆盖的属性会完整保留

备选方案(手动转换嵌套对象)

如果你因为某些限制不能用fromJS,也可以手动把嵌套的子对象转成Immutable Map,适合结构简单的场景:

const map2 = Immutable.Map({
  "foo.bar": Immutable.Map(obj2["foo.bar"])
});
const map1 = Immutable.Map({
  "foo.bar": Immutable.Map(obj1["foo.bar"])
});

const mergedResult = map2.mergeDeep(map1);
console.log(mergedResult.toJS());

内容的提问来源于stack exchange,提问作者Vinod Kolla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:32:35