【问题标题】:Return modified object in JavaScript (similar to lenses)在 JavaScript 中返回修改后的对象(类似于镜头)
【发布时间】:2019-03-03 14:52:33
【问题描述】:

与镜头在函数式语言中的功能类似,JavaScript 中是否有一种方法可以返回一个与原始对象相同但修改了一些元素的新对象?

var myObject = {
  label: 'Table',
  options: ['legs'],
  params: {
    colour: 'red',
    feet: {
      colour: 'white',
      shape: 'round'
    }
  }
}

function newObject(obj) {
  // sought-after syntax here
  return obj({ params.colour = 'green', params.feet.shape = 'square' })
}

console.log(newObject(myObject))
{
  label: 'Table',
  options: ['legs'],
  params: {
    colour: 'green',
    feet: {
      colour: 'white',
      shape: 'square'
    }
  }
}

注意:newObject() 返回一个 new 对象,不会影响任何形状或形式的原始对象。

【问题讨论】:

  • 它是一个普通的对象还是复杂的?另外,它是否有分配给它的任何函数,还是只是原语、数组和其他对象?
  • 在 JavaScript 中没有直接支持,但当然可以实现代码来做这样的事情。
  • 那将是一个仅由基元、数组和其他对象组成的对象
  • 检查 immer 或 ramda 或不可变
  • JavaScript 功能强大,您可以编写自己的镜头

标签: javascript ecmascript-6 destructuring


【解决方案1】:

您可以尝试使用传播语法

var myObject = {
  label: 'Table',
  options: ['legs'],
  params: {
    colour: 'red',
    feet: {
      colour: 'white',
      shape: 'round'
    }
  }
}

function newObject(obj) {
  // sought-after syntax here
return ({...obj,params:{...obj.params,colour:"green",feet: {...obj.params.feet,shape:"square"}}})
}

console.log(newObject(myObject))

【讨论】:

【解决方案2】:

无需嵌套,使用Object.assign 即可轻松完成:

Object.assign({}, obj, { label: "New One" })

或使用对象传播:

{ ...obj, label: "New One" }

要支持嵌套对象/数组,您必须手动递归合并对象:

 function merge(target, changes) {
   const result = {};

   for(const [key, value] of Object.entries(target).concat(Object.entries(changes))) {
     if(Array.isArray(value)) {
       // TODO
     } else if(typeof value === "object") {
       result[key] = merge(result[key] || {}, value);
     } else {
       result[key] = value;
     }
   }

   return result;
}

【讨论】:

    【解决方案3】:

    另一种替代方式是:

    let newObj = JSON.parse(JSON.stringify(oldObj))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-22
      • 2020-08-19
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      相关资源
      最近更新 更多