如何防止object/array突变?
How to prevent object/array mutation?
我一直在尝试调试奇怪的问题,我终于弄明白了为什么会这样。只是不确定如何防止它(;我有这个功能:
getInfo(id) {
id = id || "zero";
let i = routeDefinitions.findIndex(r => Boolean(r.name.toLowerCase().match(id)));
// console.log(i) - works in plunker
// but in my app sometimes returns -1...
let current = routeDefinitions[i];
let next = routeDefinitions[i + 1] ? routeDefinitions[i + 1] : false;
let prev = routeDefinitions[i - 1] ? routeDefinitions[i - 1] : false;
return { prev, current, next };
}
..它在 this plunker 中完美运行,但在我的应用程序中,我使用它的 return 值来更新应用程序状态(redux 模式的自定义实现)。当我通过此函数发送 return 值时:
private _update(_old, _new) {
let newState = Object.keys(_new)
.map(key => {
if (_old[key] === undefined) {
_old[key] = _new[key];
} else if (typeof _new[key] === "object") {
this._update(_old[key], _new[key]);
} else {
_old[key] = _new[key];
}
return _old;
})
.find(Boolean);
return Object.assign({}, newState || _old);
}
..routeDefinitions
数组发生了变化,事情开始崩溃了……我尝试了一些事情:
let current = [...routeDefinitions][i];
// and:
return Object.assign({}, { prev, current, next });
..但是没有用。如何防止 routeDefinitions
数组发生突变?
编辑:我已经成功重现了 this plunker
中的错误
routeDefinitions array is mutated and things start to break
如果你的函数是真的:
getInfo(id) {
id = id || "zero";
let i = routeDefinitions.findIndex(r => Boolean(r.name.toLowerCase().match(id)));
// console.log(i) - works in plunker
// but in my app sometimes returns -1...
let current = routeDefinitions[i];
let next = routeDefinitions[i + 1] ? routeDefinitions[i + 1] : false;
let prev = routeDefinitions[i - 1] ? routeDefinitions[i - 1] : false;
return { prev, current, next };
}
则routeDefinitions
不变异。其他东西正在改变 routeDefinitions。
我通过像这样修改 _update()
解决了这个问题:
private _update2(_old, _new) {
let newState = {};
Object.keys(_new)
.map(key => {
if (_old[key] === undefined) {
newState[key] = _new[key];
} else if (typeof _new[key] === "object") {
newState[key] = this._update2(_old[key], _new[key]);
} else {
newState[key] = _new[key];
}
return newState;
})
.find(Boolean);
return Object.assign({}, _old, newState);
}
我用old state
只是为了检查值,等_update()
完成后再修改它。
我一直在尝试调试奇怪的问题,我终于弄明白了为什么会这样。只是不确定如何防止它(;我有这个功能:
getInfo(id) {
id = id || "zero";
let i = routeDefinitions.findIndex(r => Boolean(r.name.toLowerCase().match(id)));
// console.log(i) - works in plunker
// but in my app sometimes returns -1...
let current = routeDefinitions[i];
let next = routeDefinitions[i + 1] ? routeDefinitions[i + 1] : false;
let prev = routeDefinitions[i - 1] ? routeDefinitions[i - 1] : false;
return { prev, current, next };
}
..它在 this plunker 中完美运行,但在我的应用程序中,我使用它的 return 值来更新应用程序状态(redux 模式的自定义实现)。当我通过此函数发送 return 值时:
private _update(_old, _new) {
let newState = Object.keys(_new)
.map(key => {
if (_old[key] === undefined) {
_old[key] = _new[key];
} else if (typeof _new[key] === "object") {
this._update(_old[key], _new[key]);
} else {
_old[key] = _new[key];
}
return _old;
})
.find(Boolean);
return Object.assign({}, newState || _old);
}
..routeDefinitions
数组发生了变化,事情开始崩溃了……我尝试了一些事情:
let current = [...routeDefinitions][i];
// and:
return Object.assign({}, { prev, current, next });
..但是没有用。如何防止 routeDefinitions
数组发生突变?
编辑:我已经成功重现了 this plunker
中的错误routeDefinitions array is mutated and things start to break
如果你的函数是真的:
getInfo(id) {
id = id || "zero";
let i = routeDefinitions.findIndex(r => Boolean(r.name.toLowerCase().match(id)));
// console.log(i) - works in plunker
// but in my app sometimes returns -1...
let current = routeDefinitions[i];
let next = routeDefinitions[i + 1] ? routeDefinitions[i + 1] : false;
let prev = routeDefinitions[i - 1] ? routeDefinitions[i - 1] : false;
return { prev, current, next };
}
则routeDefinitions
不变异。其他东西正在改变 routeDefinitions。
我通过像这样修改 _update()
解决了这个问题:
private _update2(_old, _new) {
let newState = {};
Object.keys(_new)
.map(key => {
if (_old[key] === undefined) {
newState[key] = _new[key];
} else if (typeof _new[key] === "object") {
newState[key] = this._update2(_old[key], _new[key]);
} else {
newState[key] = _new[key];
}
return newState;
})
.find(Boolean);
return Object.assign({}, _old, newState);
}
我用old state
只是为了检查值,等_update()
完成后再修改它。