Возврат измененного объекта в JavaScript (аналог линз) - PullRequest
0 голосов
/ 03 марта 2019

Подобно тому, что линзы могут делать в функциональных языках, есть ли в 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() возвращает новый объект, не затрагивая оригинал в любой форме или форме.

Ответы [ 3 ]

0 голосов
/ 03 марта 2019

Вы можете попробовать использовать синтаксис распространения

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))
0 голосов
/ 03 марта 2019

Другой альтернативный способ:

let newObj = JSON.parse(JSON.stringify(oldObj))
0 голосов
/ 03 марта 2019

Без вложения, который можно легко сделать с помощью 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;
}
...