select change事件触发后确认对话框未弹出,报confirm非函数错误
错误根因
问题直接出在事件回调中新增的确认逻辑这行代码:
var confirm = confirm("Do you want to update data?");
这里触发了JavaScript的作用域遮蔽问题,这也是为什么你没加确认逻辑时,整套更新功能可以正常运行,加了之后就报错:
- 你在当前的change事件回调函数作用域中,声明了一个和浏览器原生全局方法
window.confirm同名的局部变量confirm - 根据JS变量提升规则,只要在当前作用域内存在
confirm的变量声明,整个作用域内对confirm标识符的访问都会优先指向这个局部变量,而非全局的原生方法 - 代码执行到这行时,赋值操作右侧的
confirm(...)调用的不是浏览器自带的确认弹窗方法,而是当前作用域下还没完成赋值、值为undefined的局部变量confirm,因此直接抛出Uncaught TypeError: confirm is not a function错误,弹窗自然无法正常弹出。
修复方案
- 避开变量命名冲突,不要在作用域内声明和原生全局方法、内置对象同名的变量,同时明确通过全局对象调用原生确认方法,从根源上避免遮蔽问题:
// 把局部变量改成不冲突的命名,同时显式调用window上的原生confirm方法 var isUserConfirmed = window.confirm("Do you want to update data?"); if (isUserConfirmed == true) { // 原有业务逻辑 } - 可顺带优化重复的ajax逻辑:原有代码中三个分支的ajax请求除了传递的
type字段值不同,其余配置、回调逻辑完全一致,可以通过映射表抽离重复代码,降低后续维护成本:document.querySelector('#select').addEventListener("change", function() { // 先判断是否确认更新 var isUserConfirmed = window.confirm("Do you want to update data?"); if (!isUserConfirmed) { console.log("Update canceled"); return; } // 下拉值和请求type的映射关系 const statusMap = { "1": "pending", "2": "succeed", "3": "canceled" }; const requestType = statusMap[this.value]; if (!requestType) { console.log("Update canceled"); return; } // 统一发送ajax请求 $.ajax({ url: "update.php", type: "POST", data: { id: <?php echo $row['serial']?>, type: requestType }, cache: false, success: function(dataResult){ const res = JSON.parse(dataResult); if(res.statusCode == 200){ alert("Successfully updated"); location.replace("../deposit/"); } else if(res.statusCode == 201){ alert("Something went wrong"); } else { alert("Everything went wrong"); } } }); });
内容的提问来源于stack exchange,提问作者Man
相关产品推荐
相关产品推荐

