矩阵计算器单次运行后函数失效问题(疑与this关键字相关)
问题诊断与修复方案
核心问题
你遇到的问题不是this关键字导致的,而是在add()和sub()函数中,使用了与函数同名的全局变量,直接覆盖了函数本身:
- 在
add()里,add = parseInt(this[x]) + parseInt(this[y]);这行代码没有用let/const/var声明变量,会自动成为全局变量。第一次执行后,原本的add函数就被这个数值覆盖,第二次点击按钮时,add已经是个数字,无法作为函数调用。 sub()函数同理,sub = parseInt(this[x]) - parseInt(this[y]);直接覆盖了sub函数。
修复步骤
- 重命名运算结果变量:把
add换成sum,sub换成difference,并用let声明为局部变量,避免污染全局作用域。 - 简化不必要的this使用:
this["a"+i]存储输入值完全没必要,直接获取输入值后计算即可,减少冗余的全局变量。 - 修正DOM清空逻辑:清空结果容器时用
o.innerHTML = ''代替o.textContent = '',更符合后续用innerHTML添加元素的逻辑。 - 优化reg函数:
reg里已经拿到目标元素p1,直接用p1.innerHTML += ...代替重复查询DOM的document.getElementById(p2).innerHTML += ...,提升效率。
修复后的完整代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> * { font-family: 'Comic Sans MS' } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } input { font-size: 50px; text-align: center; width: 96px; height: 96px; border: 2px solid black; margin: 0px; padding: 0px; } div { position: absolute; border: 2px solid black; border-radius: 5px; width: 300px; height: 200px; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; } #d1 { top: 25px; left: 25px; } #d2 { top: 25px; right: 25px; } #o { position: absolute; top: 500px; left: 25px; align: center; } button { position: absolute; border: 4px solid black; font-size: 50px; top: 300px; left: 25px; width: 100px; height: 100px; background-color: transparent; border-radius: 5px; } #add { left: 25px; } #sub { left: 150px; } p { position: absolute; border: 2px solid black; padding: 5px; border-radius: 10px; width: 160px; top: 25px; left: 40%; font-size: 25px; display: flex; align-items: center; flex-wrap: wrap; justify-content: space-between; } #r, #c { border: 1px solid black; border-radius: 5px; height: 25px; width: 50px; font-size: 20px } </style> </head> <body> <div id="d1"> <input type="number" id="a1"> <input type="number" id="a2"> <input type="number" id="a3"> <input type="number" id="a4"> <input type="number" id="a5"> <input type="number" id="a6"> </div> <div id="d2"> <input type="number" id="b1"> <input type="number" id="b2"> <input type="number" id="b3"> <input type="number" id="b4"> <input type="number" id="b5"> <input type="number" id="b6"> </div> <button onclick="add()" id="add">+</button> <button onclick="sub()" id="sub">-</button> <div id="o"> <input type="number"> <input type="number"> <input type="number"> <input type="number"> <input type="number"> <input type="number"> </div> <p> Rows: <input type="number" id="r"> Columns: <input type="number" id="c"> </p> <script> const d1 = document.getElementById("d1"); const d2 = document.getElementById("d2"); const o = document.getElementById("o"); const rr = document.getElementById("r"); const cc = document.getElementById("c"); let r = 2; let c = 3; let t = r*c; function reg(p1, p3) { p1.style.width = 100*r+"px"; p1.innerHTML = ''; t = r*c; for (let i = 1; i <= t; i++) { p1.innerHTML += `<input type='number' id='${p3+i}'>`; } } [rr, cc].forEach(function(el) { el.addEventListener('keyup', function () { r = parseInt(rr.value) || 2; c = parseInt(cc.value) || 3; reg(d1, "a"); reg(d2, "b"); reg(o, "o"); }); }); function add() { o.innerHTML = ''; for (let i = 1; i <= t; i++) { const valA = parseInt(document.getElementById(`a${i}`).value) || 0; const valB = parseInt(document.getElementById(`b${i}`).value) || 0; const sum = valA + valB; o.innerHTML += `<input type='number' value=${sum}>`; } } function sub() { o.innerHTML = ''; for (let i = 1; i <= t; i++) { const valA = parseInt(document.getElementById(`a${i}`).value) || 0; const valB = parseInt(document.getElementById(`b${i}`).value) || 0; const difference = valA - valB; o.innerHTML += `<input type='number' value=${difference}>`; } } </script> </body> </html>
额外优化说明
- 给所有DOM元素变量加上
const声明,避免全局污染。 - 处理行列输入的非数字情况,用
parseInt(xxx) || 默认值确保数值有效。 - 使用模板字符串代替字符串拼接,代码更易读。
内容的提问来源于stack exchange,提问作者CoolBoiBS
相关产品推荐
相关产品推荐

