如何在 Javascript 中使对象不可变
how to make object immutable in Javascript
我有一个工厂函数,return是一个只有一个函数的对象。现在的问题是我想更新这个对象的值 属性 而不改变对象,我特别想要 return 一个具有所有功能和更新的 属性 的新对象
这是我试过的
function temperature(args) {
const convertToC = temperature(({ ...args }).map((x)=> Celsiusconverter(x)))//this does not work
return Object.assign({
args,
convertToC
})
}
function Celsiusconverter(args) {
const newArgs = {...args}
newArgs.value = (newArgs.value - 32) * (5 / 9)
newArgs.unit = 'C'
return {
newArgs
}
}
const temeratureObject = {
unit: 'C',
value: 10,
}
const temp = temperature(temeratureObject)
const temp2 = temp.convertToC(temeratureObject);
console.log(temp2.getValue()) // this gives me this error: TypeError: {(intermediate value)}.map is not a function
不确定 JavaScript 对象是否具有您正在尝试的地图功能 ({ ...args }).map((x)=> Celsiusconverter(x))
。
这是 Whosebug post 的解释:
map function for objects (instead of arrays)
我尝试将 JavaScript 对象更改为数组(如 Whosebug post 中所建议),这会导致堆栈溢出错误(双关语)。
一些问题:
convertToC
方法没有明确定义。您立即 执行 对 temperature()
的调用,而不是定义调用它的函数。
convertToC
方法还错误地在 non-array 上使用解构扩展语法(因此出现错误):({ ...args })
。此外,不清楚调用 .map
的想法从何而来,因为它适用于数组,而不是对象。
为了处理这个问题和上一个问题,将该定义更改为:
const convertToC = () => temperature(Celsiusconverter(args));
在下一行中,您使用一个参数调用 Object.assign
:即 null-operation。您打算 扩展 args
对象,但您定义了一个名为 args
的 属性,其中 args
作为嵌套对象值。这里你可以使用传播语法:
return {
...args,
convertToC,
getValue,
getUnit
};
在 Celsiusconverter
中你犯了类似的错误:你 return 一个带有 args
属性 的对象。你应该只是 return args
(这已经是函数参数的浅拷贝):
return args;
在主程序中,您不必将 temperatureObject
传递给 convertToC
方法,因为调用它的对象已经知道 temperatureObject
.它应该被称为:
const temp2 = temp.convertToC();
所以把所有这些放在一起你会得到:
function temperature(args) {
const getValue = () => args.value;
const getUnit = () => args.unit;
const convertToC = () => temperature(Celsiusconverter(args));
return {
...args,
convertToC,
getValue,
getUnit
};
}
function Celsiusconverter(args) {
const newArgs = {...args};
newArgs.value = (newArgs.value - 32) * (5 / 9);
newArgs.unit = 'C';
return newArgs;
}
const temperatureObject = {
unit: 'C',
value: 10,
}
const temp = temperature(temperatureObject);
const temp2 = temp.convertToC();
console.log(temp2.getValue());
我有一个工厂函数,return是一个只有一个函数的对象。现在的问题是我想更新这个对象的值 属性 而不改变对象,我特别想要 return 一个具有所有功能和更新的 属性 的新对象 这是我试过的
function temperature(args) {
const convertToC = temperature(({ ...args }).map((x)=> Celsiusconverter(x)))//this does not work
return Object.assign({
args,
convertToC
})
}
function Celsiusconverter(args) {
const newArgs = {...args}
newArgs.value = (newArgs.value - 32) * (5 / 9)
newArgs.unit = 'C'
return {
newArgs
}
}
const temeratureObject = {
unit: 'C',
value: 10,
}
const temp = temperature(temeratureObject)
const temp2 = temp.convertToC(temeratureObject);
console.log(temp2.getValue()) // this gives me this error: TypeError: {(intermediate value)}.map is not a function
不确定 JavaScript 对象是否具有您正在尝试的地图功能 ({ ...args }).map((x)=> Celsiusconverter(x))
。
这是 Whosebug post 的解释: map function for objects (instead of arrays)
我尝试将 JavaScript 对象更改为数组(如 Whosebug post 中所建议),这会导致堆栈溢出错误(双关语)。
一些问题:
convertToC
方法没有明确定义。您立即 执行 对temperature()
的调用,而不是定义调用它的函数。convertToC
方法还错误地在 non-array 上使用解构扩展语法(因此出现错误):({ ...args })
。此外,不清楚调用.map
的想法从何而来,因为它适用于数组,而不是对象。为了处理这个问题和上一个问题,将该定义更改为:
const convertToC = () => temperature(Celsiusconverter(args));
在下一行中,您使用一个参数调用
Object.assign
:即 null-operation。您打算 扩展args
对象,但您定义了一个名为args
的 属性,其中args
作为嵌套对象值。这里你可以使用传播语法:return { ...args, convertToC, getValue, getUnit };
在
Celsiusconverter
中你犯了类似的错误:你 return 一个带有args
属性 的对象。你应该只是 returnargs
(这已经是函数参数的浅拷贝):return args;
在主程序中,您不必将
temperatureObject
传递给convertToC
方法,因为调用它的对象已经知道temperatureObject
.它应该被称为:const temp2 = temp.convertToC();
所以把所有这些放在一起你会得到:
function temperature(args) {
const getValue = () => args.value;
const getUnit = () => args.unit;
const convertToC = () => temperature(Celsiusconverter(args));
return {
...args,
convertToC,
getValue,
getUnit
};
}
function Celsiusconverter(args) {
const newArgs = {...args};
newArgs.value = (newArgs.value - 32) * (5 / 9);
newArgs.unit = 'C';
return newArgs;
}
const temperatureObject = {
unit: 'C',
value: 10,
}
const temp = temperature(temperatureObject);
const temp2 = temp.convertToC();
console.log(temp2.getValue());