使用splice向数组随机插入元素时报错:无法定义不可写长度数组索引
问题描述
尝试向长度为3的数组中随机插入一个字符串时,控制台抛出错误:Uncaught TypeError: can't define array index property past the end of an array with non-writable length
具体场景:将服务器返回的obj.incorrect_answers(固定为3个字符串的数组)赋值给answers后,想用splice在0-3的随机索引位置插入obj.correct_answer字符串。
相关代码片段:
export const Home = () => { const [id, setId] = useState(0); const dispatch = useDispatch(); const obj = useSelector((state) => state.questions.data[id]); const fetchStatus = useSelector((state) => state.questions.status); if(obj){ let answers = obj.incorrect_answers; answers.splice(Math.floor(Math.random()*4), 0, obj.correct_answer); console.log(answers); } useEffect(() => { if(fetchStatus === "idle"){ dispatch(fetchQuestions()); } }, [fetchStatus])
已确认服务器返回数据格式正确,怀疑问题出在splice操作或服务器返回数组的特性上。
问题原因与解决办法
核心原因:服务器返回的
obj.incorrect_answers数组是**长度不可写(non-writable length)**的只读数组,可能是被Object.freeze()冻结,或是第三方API返回的不可扩展数组。直接修改这类数组的结构会触发长度不可写的报错。解决步骤:
- 创建原数组的可修改副本:不要直接操作服务器返回的原数组,先复制出一份可编辑的新数组再执行插入操作,修改后的代码如下:
if(obj){ // 用扩展运算符创建可修改的数组副本 let answers = [...obj.incorrect_answers]; // 也可以用Array.from实现相同效果 // let answers = Array.from(obj.incorrect_answers); answers.splice(Math.floor(Math.random()*4), 0, obj.correct_answer); console.log(answers); } - 随机索引逻辑无需调整:原数组长度为3,插入位置范围0-3(包含),
Math.floor(Math.random()*4)的取值正好覆盖该范围,逻辑是正确的。
- 创建原数组的可修改副本:不要直接操作服务器返回的原数组,先复制出一份可编辑的新数组再执行插入操作,修改后的代码如下:
内容的提问来源于stack exchange,提问作者Arman Ebrahimi
相关产品推荐
相关产品推荐

