创建一个返回具有不可变状态的对象的工厂函数

时间:2017-07-28 05:12:53

标签: javascript ecmascript-6 state immutability factory

链接到CodePen https://codepen.io/jaspercreel/pen/Mvaodp

基本上,我的功能看起来像这样:

const Factory = (args) => {

  const state = {
    args
  }

  const methods = {  

    getState() => {
      return args;
    },

    setState(args) => {
      state.args = args;
    },

    doStuffWithState() => {
      let args = this.getState();
      function(args) {
        return args plus something else;
      }();
    }

  }

  return Object.assign({}, methods);

}

问题在于,每当我调用doStuffWithState()时,它都会更改状态对象。我认为使用返回的状态创建一个新变量是安全的,但我了解到引用一个对象时,你只是创建一个新的引用。所以我的问题是,如何在工厂函数中创建可引用但不更改(除了辅助函数)的不可变状态?

我的最终目标是创建一个分拣机工厂函数,该函数将创建一个对象,该对象采用数组并进行排序并以不同方式搜索它们。我希望能够在分类器中存储一个默认数组,该数组可以被引用以返回不同的排序选项但不会更改。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

一种方法是将JavaScript对象存储为JSON字符串JSON.stringify()并使用JSON.parse()JSON字符串解析为JavaScript对象,而不是引用传递的原始对象,存储为字符串。

您还可以利用Promise返回反映JSON字符串属性的JavaScript对象,传递给Object.assign(),可以返回原始对象的修改属性或值,而不会影响原始对象传递给Factory,它返回Promise值作为原始传递对象的JSON字符串格式。

// `const` declaration cannot be changed or deleted
const Factory = (args) => Promise.resolve(JSON.stringify(args));

const state = Factory({
  abc: [1, 2, 3]
});

state.then(data => console.log(data)); // `{"abc":[1,2,3]}`

// change object passed to `Factory`
state.then(data => Object.assign(JSON.parse(data), {
    abc: JSON.parse(data).abc.concat(4, 5, 6)
}))
// do stuff with modified `JSON` `args` as JavaScript object
.then(res => {console.log(res); return res}) // `{"abc":[1,2,3,4,5,6]}`
.then(res =>
  // `res` : `{"abc":[1,2,3,4,5,6]}`
  // `state` `Promise` value is original object 
  // as valid `JSON` `{"abc":[1,2,3]}`
  // return original `args` as `JSON` string
  state.then(data => {console.log(res, data); return data})
)
// original `args` as JavaScript object
.then(o => console.log(JSON.parse(o)))

答案 1 :(得分:1)

我很欣赏所有答案和评论。事实证明我非常愚蠢。因此,在我的测试中,我有时能够在不改变原始值的情况下返回值,有时不会,并且我无法弄清楚原因。现在我知道这是因为在我的测试中改变了状态,我在数组上调用sort(),而sort是一个就地函数。它改变了原始数组。我这么小的疏忽,但我认为这是一种学习经历。再次感谢帮助人员的努力。希望我的愚蠢错误也可以成为其他人的学习经历。