在JavaScript编程中,以函数式方式编程是一个巨大的优势。我正在尝试以函数式方式修改包含在对象数组中的对象的属性,这意味着传递给map
函数的对象项不能被修改。如果我这样做:
const modObjects = objects.map((item) => {
item.foo = "foo" + 3;
return item;
});
这段代码出现问题是因为在函数内部修改了item,导致该功能无法正常使用。你知道其他解决这个问题的方法吗?
在JavaScript编程中,以函数式方式编程是一个巨大的优势。我正在尝试以函数式方式修改包含在对象数组中的对象的属性,这意味着传递给map
函数的对象项不能被修改。如果我这样做:
const modObjects = objects.map((item) => {
item.foo = "foo" + 3;
return item;
});
这段代码出现问题是因为在函数内部修改了item,导致该功能无法正常使用。你知道其他解决这个问题的方法吗?
一种新的(ES6)方式,非常不可变且符合函数式编程的精神:
// A. Map function that sets obj[prop] to a fixed value
const propSet = prop => value => obj => ({...obj, [prop]: value})
// B. Map function that modifies obj.foo2 only if it exists
const foo2Modify = obj =>
obj.hasOwnProperty('foo2') ? {...obj, foo2: 'foo ' + obj.foo2} : obj
// Usage examples of A and B
const initialData = [{'foo': 'one'}, {'foo2': 'two'}, {'foo3': 'three'}]
const newData1 = initialData.map(propSet('foo2')('bar')) // Set value
const newData2 = initialData.map(foo2Modify) // Use a modify function
console.log(initialData) // Initial data should not change
console.log(newData1) // Each object should contain the new fixed foo2
console.log(newData2) // Modify foo2 only if it exists in initial data
{...obj, [prop]: value}
?我对方括号感到困惑。 - Michael DorstObject.assign
来创建一个item对象的副本,并从map回调函数中返回该副本。
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)
data
中有对可变对象的引用,那么newData
的引用透明性将会被破坏。 - etherealiteconst modObjects = objects.map(
item => ({...item, foo: item.foo + 3})
)
()
,它们需要消除lambda中代码块{}
与对象字面量{}
的歧义。另一种方法是使用带有return
的代码块:const modObjects = objects.map(
item => { return {...item, foo: item.foo + 3} }
)
const modObjects = objects.map((item) => {
return { ...objects, foo: "foo" + 3; };
});
objects.map((item) => { ...destSchema, foo: "foo" + 3; });
无法正常工作的原因是为了让JS解释器明白它是一个作用域还是一个对象而特意这样设计的。你必须使用return
。function mapProperty<T>(prop: string){
return (cb: (propValue: any) => any) => (obj: any) => ({...obj, [prop]: cb(obj[prop])}) as (T)
}
item
,更改属性,返回副本。 - thefourtheye