我对javascript并不陌生,并且会做出反应(16.9.0),所以我希望这个问题不太明显:
我知道我可以用'...'复制字典,例如:const dict_new = {... dict_old}我正在使用此表达式来避免引用副本。问题是,当我在异步componentDidMount()内定义字典并制作副本时,尽管定义正确,但该副本仍是引用的副本。让我展示我的代码:
async componentDidMount() {
try {
const res1 = await fetch('/postmongo/group/');
let grupos = await res1.json();
const res2 = await fetch('/postmongo/permiso/');
const permisos = await res2.json();
const dict_permisos = {};
permisos.forEach((perm) => {
dict_permisos[perm.descripcion] = {};
grupos.forEach((gr) => {
if (gr.Permisos_gemelo.some((p) => (p.nombre === perm.nombre))) {
dict_permisos[perm.descripcion][gr.name] = true;
} else {
dict_permisos[perm.descripcion][gr.name] = false;
}
});
});
const dict_permisos_inicial = {...dict_permisos}
this.setState({
grupos,
permisos,
dict_permisos,
dict_permisos_inicial,
});
console.log(this.state);
} catch (e) {
console.log(e);
}
}
dict_permisos_inicial是引用副本(即,当dict_permisos更改时,它正在更改),它应该是独立的。我想念什么?我通过两次定义字典来解决,也许我应该在componentDidMount()之外构建字典,但是,在哪里?
尝试Object.assign
大多数情况下,对象重置和散布都以相同的方式进行,主要区别在于散布定义属性,而Object.assign()设置属性。这意味着Object.assign()触发设置器。
值得记住的是,除此之外,对象休息/扩展1:1映射到Object.assign()并以不同的方式作用于数组(可迭代)扩展。例如,在扩展数组时,将扩展空值。但是,使用对象传播时,空值会默默地传播为零。
数组(可迭代)传播示例
const x = [1, 2, null , 3];
const y = [...x, 4, 5];
const z = null;
console.log(y); // [1, 2, null, 3, 4, 5];
console.log([...z]); // TypeError
对象传播示例
const x = null;
const y = {a: 1, b: 2};
const z = {...x, ...y};
console.log(z); //{a: 1, b: 2}
谢谢大家,我在此博客中找到了解决方案:https://medium.com/javascript-in-plain-english/how-to-deep-copy-objects-and-arrays-in-javascript-7c911359b089
转录他的话:“对于包含其他对象或数组的对象和数组,复制这些对象需要深度复制。否则,对嵌套引用的更改将更改嵌套在原始对象或数组中的数据。”
基本上,使用const dict_permisos_inicial = {... dict_permisos},我正在执行浅表复制,并且使用简单的字典可以正常工作。但是,我的字典是嵌套的,浅标准副本不起作用。例如:
> dict = {
... permiso1: { grupo1: true, grupo2: false },
... permiso2: { grupo1: false, grupo2: true }
... }
{
permiso1: { grupo1: true, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict_copy = {...dict}
{
permiso1: { grupo1: true, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict_copy["permiso1"]["grupo1"]=false
false
> dict_copy
{
permiso1: { grupo1: false, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict
{
permiso1: { grupo1: false, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
根据他展示的解决方案,我使用了“ ramda”。在React中:
import { clone } from 'ramda'
[some code]
const dict_permisos_inicial = clone(dict_permisos);
在节点中:
> var R = require("ramda")
undefined
> dict_copy = R.clone(dict)
{
permiso1: { grupo1: true, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict_copy["permiso1"]["grupo1"]=false
false
> dict_copy
{
permiso1: { grupo1: false, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict
{
permiso1: { grupo1: true, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}