![](/img/trans.png)
[英]JavaScript: Create Factory Function that Returns Object with Methods That Have Specific Properties
[英]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.