我正在寻找一个与lodash的_.set
相同的功能,除了它应该返回一个新对象而不修改原始对象。这有什么实现吗?
现在我正在进行深度克隆,然后进行设置:
let data = _.cloneDeep(this.state.data);
_.set(data, name, value);
this.setState({data})
但是我不认为有必要进行完全深度克隆,我们只需要在最深层次对物体进行浅层克隆,不是吗?
e.g。
let oldData = { 'a': [{ 'b': { 'c': 3 }, 'd': {'e': 4} }] };
let newDate = withValue(oldData, 'a[0].b.c', 5);
建议的withValue
函数会执行a
,a[0]
和a[0].b
的浅层复制,然后将新的a[0].b.c
修改为5.我们不会需要复制a[0].d
。
答案 0 :(得分:4)
这将是一个多部分的答案。
不可变集:
当您使用lodash时,您可以使用FP version of lodash并使用.set
(或.setWith
来提供对象路径),这将执行不可变更新。< / p>
或者,因为这看起来像React代码库,您可以使用$set
helper of React。
或者您可以使用Spread Operator:
const newObj = {...oldObj, prop: newValue }
或Object.assign:
const newObj = Object.assign({}, oldObj, { prop: newValue });
<强>性能:强>
当你提到性能(而不只是深度克隆一个对象)时,你可能想要查看一个不可变的框架。更开发的代码库通过不同的措施提高性能。例如。这是immutable.js所说的:
通过使用哈希映射尝试和向量尝试进行结构共享,这些数据结构在现代JavaScript虚拟机上非常高效
...... Mori说:
高效的不可变数据结构 - 无需克隆[...] V8,JavaScriptCore和SpiderMonkey等现代JavaScript引擎可提供实现持久数据结构所需的性能。
答案 1 :(得分:3)
lodash/fp Emil suggested应该有效。
示例:
const setIn = require('lodash/fp/set');
this.setState({data: setIn(name, value, this.state.data)});
N.B。参数顺序与常规lodash不同。