以函数方式修改对象的属性

modify a property of an object in the functional way

本文关键字:属性 对象 修改 函数 方式      更新时间:2023-09-26

在javascript编程中以函数方式是一大好处。我试图以函数的方式修改对象数组中包含的对象的属性,这意味着不能修改map函数中传递的对象项。如果我这样做:

const modObjects = objects.map((item) => {
   item.foo = "foo" + 3;
   return 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

您可以使用Object.assign创建项obj的副本,并从映射回调返回该副本。

Object.assign()

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)

您也可以这样做:

const modObjects = objects.map((item) => {
   return { ...objects, foo: "foo" + 3; };
});

objects.map((item) => { ...destSchema, foo: "foo" + 3; });不起作用的原因是他们用这种方式让JS解释器理解它是作用域还是对象。您必须使用return

在现代JavaScript中,您可以在对象文字内部的对象上使用扩展运算符:

const modObjects = objects.map(
  item => ({...item, foo: item.foo + 3})
)

注意对象文字周围的括号()。需要它们来消除lambdas中的代码块{}中的对象文字{}的歧义。另一种方法是将代码块与return:一起使用

const modObjects = objects.map(
  item => { return {...item, foo: item.foo + 3} }
)

我扩展了@Dimitrios Tsalkakis answer,用回调函数更改属性。

示例:https://repl.it/@robie2011/ts设置属性函数

打字:

function mapProperty<T>(prop: string){
    return (cb: (propValue: any) => any) => (obj: any) => ({...obj, [prop]: cb(obj[prop])}) as (T)
}