使用扩展运算符和析构函数运算符修改不可变对象的最短方法是什么
What is the shortest way to modify immutable objects using spread and destructuring operators
我正在寻找一个纯函数来修改我的不可变状态对象。作为参数给定的原始状态必须保持不变。这在处理像Redux这样的框架时尤其有用,并使处理javascript中的不可变对象变得更加容易。特别是因为使用Babel处理对象扩散操作符已经是可能的。
我没有发现比第一次复制对象和分配/删除我想要的属性更好的东西:
function updateState(state, item) {
newState = {...state};
newState[item.id] = item;
return newState;
}
function deleteProperty(state, id) {
var newState = {...state};
delete newState[id];
return newState;
}
我觉得可能更短
对状态的操作,其中状态被认为是不可变的。
添加或更新属性值:
// ES6:
function updateState(state, item) {
return Object.assign({}, state, {[item.id]: item});
}
// With Object Spread:
function updateState(state, item) {
return {
...state,
[item.id]: item
};
}
删除属性
// ES6:
function deleteProperty(state, id) {
var newState = Object.assign({}, state);
delete newState[id];
return newState;
}
// With Object Spread:
function deleteProperty(state, id) {
let {[id]: deleted, ...newState} = state;
return newState;
}
// Or even shorter as helper function:
function deleteProperty({[id]: deleted, ...newState}, id) {
return newState;
}
// Or inline:
function deleteProperty(state, id) {
return (({[id]: deleted, ...newState}) => newState)(state);
}
一个支持Object.assign
:的ES6解决方案
const updateState = (state, item) => Object.assign({}, state, { [item.id]: item });
在映射函数中
要在映射函数中执行此过程(在每个对象上删除一个属性并添加一个新属性),请给定一个对象数组-
const myArrayOfObjects = [
{id: 1, keyToDelete: 'nonsense'},
{id: 2, keyToDelete: 'rubbish'}
];
删除属性keyToDelete
,并添加值为"someVar"
的新密钥newKey
。
myArrayOfObjects.map(({ keyToDelete, ...item}) => { ...item, newKey:'someVar'});
将阵列更新为
[
{id: 1, newKey:'someVar'},
{id: 2, newKey:'someVar'}
]
有关删除方法的更多信息,请参阅这篇伟大的文章。
您可以使用一些库来做同样的事情,而不是编写难以阅读的样板代码(如上所述:(({[id]: deleted, ...state}) => state)(state)
):
- https://github.com/cah4a/immutable-modify
- https://github.com/kolodny/immutability-helper
- https://github.com/M6Web/immutable-set
- https://github.com/bormind/immutable-setter
例如:
import {remove} from 'immutable-modify'
function updateState(state, item) {
return remove(state, item.id)
}
它还支持任何嵌套更新:
import {set} from 'immutable-modify'
function updateState(state, item) {
return set(state, 'user.products', (products) => ({
...products,
items: products.items.concat(item),
lastUpdate: Date.now()
}))
}
尝试:
const { id, ...noId } = state;
测试:
console.log(noId);
从数组中删除项,只需使用filter;)
CASE 'REMOVE_ITEM_SUCCESS':
let items = state.items.filter(element => element._id !== action.id);
return {
...state,
items
}
相关文章:
- 在 JavaScript 对象中设置要使用的运算符的属性
- 使用+=运算符未定义对象中的第一个元素
- 使用扩展运算符和析构函数运算符修改不可变对象的最短方法是什么
- 什么's具有fn's赋值运算符两侧的名称(一个对象fn)
- 使用或运算符为对象指定值
- Symfony2 JSON 对象 - 错误未捕获类型错误:无法使用“in”运算符搜索“636”
- ES6 扩展运算符在对象上的应用是标准的 ECMAScript 规范吗?
- JavaScript 中对象的运算符 == 和 ===
- Angular2 在带有正斜杠的对象键上使用猫王运算符
- 通过使用 AngularJS 遵循 OR 运算符仅过滤对象中的特定字段
- 如果未使用新运算符,则返回新对象
- 为什么删除运算符返回 true,即使属性未从对象中删除
- D3:对象调用前的 + 运算符
- 为什么当我执行这个 JavaScript 语句来创建一个新的 Number 对象(使用 new 运算符)时,Chrome
- 了解JavaScript对象、数组和[]运算符
- javascript中的新运算符和对象
- 循环对象以使用javascript/Jquery创建AND运算符
- Javascript三元运算符(?:)在单个块中更改和返回对象
- 为什么用新运算符调用Javascript全局对象时会有所不同
- 与typeof运算符一起使用时,javascript null返回对象