如何在JavaScript中每次调用函数时重置对象?
解决对象引用导致的状态累加问题
问题根源
原代码中var afcUpdate = arsenal属于对象引用赋值,这意味着afcUpdate和arsenal指向内存中的同一个对象。每次点击按钮修改afcUpdate的属性时,原arsenal对象的状态也会被同步修改,导致后续点击都是基于上一次修改后的状态继续累加,无法重置回初始值。
另外原代码中还有一处逻辑错误:afcUpdate.gd = afcUpdate + as - ao,直接将对象afcUpdate参与运算会触发字符串转换,导致净胜球计算完全错误,应该改为基于afcUpdate.gd的数值运算。
解决方案
- 使用
structuredClone(arsenal)创建原对象的深拷贝,每次点击按钮时生成一个独立的新对象副本,修改副本不会影响原arsenal的初始状态。 - 修正净胜球的计算逻辑,确保是数值运算。
- 修正HTML中下拉选项的
value属性错误(比如<option value=1 0>9</option>应改为<option value=9>9</option>,避免值解析异常)。
修正后的代码
JavaScript代码
const arsenal = { name: "Arsenal", played: 19, wins: 16, draws: 2, gd: 29, }; document.querySelector('#update').addEventListener('click', function() { // 创建原对象的深拷贝,每次都基于初始状态计算 var afcUpdate = structuredClone(arsenal); var asSelect = document.getElementById("as"); var as = parseInt(asSelect.options[asSelect.selectedIndex].value); var aoSelect = document.getElementById("ao"); var ao = parseInt(aoSelect.options[aoSelect.selectedIndex].value); if (as > ao) { afcUpdate.wins++; afcUpdate.played++; } if (as === ao) { afcUpdate.draws++; afcUpdate.played++; } // 补充负场的场次统计(符合真实积分逻辑) if (as < ao) { afcUpdate.played++; } // 修正净胜球计算逻辑 afcUpdate.gd = afcUpdate.gd + (as - ao); // 计算积分并更新页面(用textContent替代innerHTML更安全) document.querySelector('#feedback2').textContent = (afcUpdate.wins * 3) + afcUpdate.draws; })
HTML代码
who will win the league <div class="game"> Arsenal <select id="as"> <option value="0">0</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> </select> <select id="ao"> <option value="0">0</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> </select> Everton </div> <button id="update">Update Table</button> <p id="feedback2"></p>
额外说明
structuredClone是ES2022引入的API,支持深拷贝大多数JavaScript类型,对于简单对象完全适用。如果需要兼容旧环境,也可以使用JSON.parse(JSON.stringify(arsenal))(但注意这种方法无法拷贝函数、Symbol等特殊类型)。- 代码中补充了比赛场次
played的递增逻辑,符合真实的联赛积分规则;同时将innerHTML改为textContent,避免潜在的XSS风险。
内容的提问来源于stack exchange,提问作者Tjunk
相关产品推荐
相关产品推荐

