链接到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()时,它都会更改状态对象。我认为使用返回的状态创建一个新变量是安全的,但我了解到引用一个对象时,你只是创建一个新的引用。所以我的问题是,如何在工厂函数中创建可引用但不更改(除了辅助函数)的不可变状态?
我的最终目标是创建一个分拣机工厂函数,该函数将创建一个对象,该对象采用数组并进行排序并以不同方式搜索它们。我希望能够在分类器中存储一个默认数组,该数组可以被引用以返回不同的排序选项但不会更改。有什么建议吗?
答案 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是一个就地函数。它改变了原始数组。我这么小的疏忽,但我认为这是一种学习经历。再次感谢帮助人员的努力。希望我的愚蠢错误也可以成为其他人的学习经历。