不可移动地移除对象中的属性
我正在使用Redux。 在我的reducer中,我试图从像这样的对象中移除一个属性:
const state = { a: '1', b: '2', c: { x: '42', y: '43' }, } 我想要这样的东西,而不必改变原来的状态:
 const newState = { a: '1', b: '2', c: { x: '42', }, } 
我试过了:
 let newState = Object.assign({}, state); delete newState.cy 
但由于某些原因,它从两个州删除财产。
可以帮助我做到这一点?
 我发现ES5的数组方法像filter , map和reduce有用的,因为他们总是返回新的数组或对象。 在这种情况下,我会使用Object.keys迭代对象, Array#reduce将其重新转换为对象。 
 return Object.assign({}, state, { c: Object.keys(state.c).reduce((result, key) => { if (key !== 'y') { result[key] = state.c[key]; } return result; }, {}) }); 
 你可以使用lodash库中的_.omit(object, [paths]) 
 path可以嵌套,例如: _.omit(object, ['key1.key2.key3']) 
 这是因为您正在将state.c的值复制到另一个对象。 而这个值是一个指向另一个JavaScript对象的指针。 所以,这两个指针都指向同一个对象。 
尝试这个:
 let newState = Object.assign({}, state); console.log(newState == state); // false console.log(newState.c == state.c); // true newState.c = Object.assign({}, state.c); console.log(newState.c == state.c); // now it is false delete newState.cy; 
你也可以做一个对象的深层拷贝。 看到这个问题 ,你会发现什么是最适合你的。
这个怎么样:
 function removeByKey (myObj, deleteKey) { return Object.keys(myObj) .filter(key => key !== deleteKey) .reduce((result, current) => { result[current] = myObj[current]; return result; }, {}); } 
它过滤应该删除的密钥,然后从剩余的密钥和初始对象中构build一个新的对象。 这个想法是从泰勒麦吉尼斯真棒reactjs程序被盗。
JSBin
 function dissoc(key, obj) { copy = Object.assign({}, obj) delete copy[key] return copy } 
另外,如果要寻找一个函数式编程工具包,请看Ramda 。
Immutable.js很简单:
 const newState = state.deleteIn(['c', 'y']); 
deleteIn()的描述
你可以使用Immutability helper来取消一个属性,在你的情况下:
 import update from 'immutability-helper'; const updatedState = update(state, { c: { $unset: ['y'] } }); 
如何使用解构赋值语法?
 const original = { foo: 'bar', stack: 'overflow', }; // If the name of the property to remove is constant const { stack, ...withoutFirst } = original; console.log(withoutFirst); // Will be { "foo": "bar" } // If the name of the property to remove is from a variable const key = 'stack' const { [key]: value, ...withoutSecond } = original; console.log(withoutSecond); // Will be { "foo": "bar" } // To do a deep removal with property names from variables const deep = { foo: 'bar', c: { x: 1, y: 2 } }; const parentKey = 'c'; const childKey = 'y'; // Remove the 'c' element from original const { [parentKey]: parentValue, ...noChild } = deep; // Remove the 'y' from the 'c' element const { [childKey]: removedValue, ...childWithout } = parentValue; // Merge back together const withoutThird = { ...noChild, [parentKey]: childWithout }; console.log(withoutThird); // Will be { "foo": "bar", "c": { "x": 1 } } 
我通常使用
 Object.assign({}, existingState, {propToRemove: undefined}) 
我意识到这不是实际上删除财产,但几乎所有的目的1其function相当。 这个语法比我认为是一个很好的折衷scheme要简单得多。
  1如果您正在使用hasOwnProperty() ,则需要使用更复杂的解决scheme。 
 你可以使用React不变性帮助器来覆盖整个c ,或者把y的值设置为undefined或null 。 这取决于你的使用情况,哪个最适合: 
 const newState = update(state, { c: {$set: { x: '42', }}, }); 
要么
 const newState2 = update(state, { c: { y: {$set: undefined}, }, });