Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/454.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用扩展和分解运算符修改不可变对象的最短方法是什么_Javascript_Destructuring_Ecmascript Next - Fatal编程技术网

Javascript 使用扩展和分解运算符修改不可变对象的最短方法是什么

Javascript 使用扩展和分解运算符修改不可变对象的最短方法是什么,javascript,destructuring,ecmascript-next,Javascript,Destructuring,Ecmascript Next,我正在寻找一个纯函数来修改我的不可变状态对象。作为参数给定的原始状态必须保持不变。这在使用框架(如)时特别有用,并使使用javascript中的对象更容易。特别是因为使用对象扩展操作符已经是可能的 我没有找到比第一次复制对象和分配/删除我想要的属性更好的方法,如下所示: function updateState(state, item) { newState = {...state}; newState[item.id] = item; return newState; } fun

我正在寻找一个纯函数来修改我的不可变状态对象。作为参数给定的原始状态必须保持不变。这在使用框架(如)时特别有用,并使使用javascript中的对象更容易。特别是因为使用对象扩展操作符已经是可能的

我没有找到比第一次复制对象和分配/删除我想要的属性更好的方法,如下所示:

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);
}

具有更多支持的ES6解决方案是:


从数组中删除项,只需使用filter;)


您可以使用一些库来完成同样的工作,而不是编写难以阅读的样板代码(如上所述:
({[id]:deleted,…state})=>state)(state)

例如:

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 myArrayOfObjects = [
    {id: 1, keyToDelete: 'nonsense'},
    {id: 2, keyToDelete: 'rubbish'}
];
删除属性
keytodele
,并添加一个值为
“someVar”
的新键
newKey

将数组更新为

[
    {id: 1, newKey:'someVar'},
    {id: 2, newKey:'someVar'}
]
有关删除方法的更多信息,请参阅。

尝试:

const { id, ...noId } = state;
和测试:

console.log(noId);

问了几秒钟后回答你自己的问题?!我使用问题表单下方的字段来回答,因为我在发布问题之前找到了解决方案。因为谷歌很难找到它,所以我把它放在这里的每个人身上。但实际上,移除一个财产也是一个有趣的问题。由于将属性设置为“未定义”,因此不会删除键,并且删除在对象定义中似乎不起作用;)你声称是ES7的东西不是ES7。对象扩散和休息仍然是一个建议。它很可能会在2017年的ES2017年到来。我希望我能投更多的票。我已经多次回到这篇文章了,当然,这在ES5风格中也是一样的。很抱歉,我必须更新这个问题。为此使用babel es6+插件;)有点困惑。实际上箭头函数只在ES6中可用,所以这个代码段是ES6。
[
    {id: 1, newKey:'someVar'},
    {id: 2, newKey:'someVar'}
]
const { id, ...noId } = state;
console.log(noId);