在javascript编程中的功能方式是一个很大的好处。我试图以功能方式修改对象数组中包含的对象的属性,这意味着无法修改作为map
函数中传递的对象的项。如果我做这样的事情:
const modObjects = objects.map((item) => {
item.foo = "foo" + 3;
return item;
});
这不起作用,因为在函数内修改了item。你知道其他任何解决这个问题的方法吗?
答案 0 :(得分:2)
一种新的(ES6)方式真正不可变并且本着函数式编程的精神:
const propValueSet = (prop) => (value) => (obj) => ({...obj, [prop]: value})
const data = [{"foo": "one"}, {"foo2": "two"}, {"foo3": "three"}]
const newData = data.map(propValueSet('foo2')('bar'))
console.log(data) // Should not change after mapping
console.log(newData) // Each object should contain the new foo2

答案 1 :(得分:1)
您可以使用Object.assign
创建项obj的副本,并从地图回调中返回该副本。
Object.assign()方法用于将所有可枚举的自有属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
这是一个例子
let data = [
{"foo": "one"},
{"foo": "two"},
{"foo": "three"}
]
let newData = data.map( item => {
let itemCopy = Object.assign({}, item);
itemCopy.foo = "foo " + item.foo;
return itemCopy;
})
console.log(data)
console.log(newData)
答案 2 :(得分:0)
您也可以这样:
const modObjects = objects.map((item) => {
return { ...objects, foo: "foo" + 3; };
});
objects.map((item) => { ...destSchema, foo: "foo" + 3; });
不起作用的原因是,他们这样做是为了使JS解释器了解它是作用域还是对象。您必须使用return
答案 3 :(得分:0)
在现代JavaScript中,您可以为此在对象文字内部的对象上使用扩展运算符:
const modObjects = objects.map(
item => ({...item, foo: item.foo + 3})
)
在对象文字周围用括号()
引起来。需要使用它们来消除lambda中的代码块{}
中的对象文字{}
的歧义。另一种方法是将代码块与return
一起使用:
const modObjects = objects.map(
item => { return {...item, foo: item.foo + 3} }
)
答案 4 :(得分:0)
我扩展了@Dimitrios Tsalkakis的答案,以使用回调函数来更改属性。
示例:https://repl.it/@robie2011/ts-set-property-functional
打字稿:
function mapProperty<T>(prop: string){
return (cb: (propValue: any) => any) => (obj: any) => ({...obj, [prop]: cb(obj[prop])}) as (T)
}