繁体   English   中英

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

[英]Create a factory function that returns an object with immutable state

链接到 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() 时,它都会更改状态对象。 我以为用返回的状态创建一个新变量是安全的,但我了解到,在引用一个对象时,你只是在创建一个新的引用。 所以我的问题是,如何在工厂函数中创建可以引用但不能更改(辅助函数除外)的不可变状态?

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

一种方法是使用JSON.stringify()将 JavaScript 对象存储为JSON字符串,并使用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)))

我感谢所有的答案和评论。 事实证明我很愚蠢。 所以在我的测试中,有时我能够在不改变原始值的情况下返回一个值,有时则不能,我无法弄清楚为什么。 现在我知道这是因为在我改变状态的测试中,我在数组上调用 sort(),而 sort 是一个就地函数。 它改变了原始数组。

我的疏忽如此之小,但我认为这是一种学习经验。 再次感谢帮助人员的努力。 希望我的愚蠢错误也能成为其他人的学习经验。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM