JavaScript传递请求返回数据时空值处理失效问题咨询
问题:直接传递请求数据时空值判断失效,二次请求却正常生效
当把请求获取的数据作为参数传递给函数时,空值合并(nullish coalescing)等空值判断完全无效,数据为空时无法给变量赋值默认内容;但通过传递ID再次发起请求获取该数据时,空值处理就能正常工作。
失效的实现方式
function getQ(CatID) { CtID = CatID let xhr = new XMLHttpRequest(); xhr.open('GET', '<?php echo base_url('Main/getQ') ?>?ID=' + CatID); xhr.send(); xhr.onload = function() { let response = JSON.parse(xhr.responseText); renderQuestions(response); } }; function renderQuestions(response) { let html = ''; for (let i = 0; i < response.length; i++) { let auditDate = response[i].AuditDate; if (auditDate == '' || auditDate == null) { let newTime = new clock() auditDate = newTime.getCurrentTime(); } else { auditDate = response[i].AuditDate.split(" ")[0]; } html += ` <tr class="tablerows"> <td><button class="btn btn-icon btn-primary" onclick="openmodal('${response[i].BeforeInspectedDate}')">CAP</button></td> </tr> `; } } // 数据为空时无法赋值默认时间,仅数据存在时生效 function openmodal(BeforeInspectedDate) { let beforedate = document.getElementById('bdate') const newtime = new clock() // 尝试过空值合并等其他条件均无效 if (!BeforeInspectedDate) { beforedate.value = newtime.getCurrentTime(); } else { let newbeforedate = BeforeInspectedDate.split(' ')[0] beforedate.value = newafterdate; // 注意此处存在笔误:newafterdate未定义 } }
有效的实现方式
// 按钮拼接改为传递ID <td><button class="btn btn-icon btn-primary" onclick="openmodal(${response[i].AuditDetailID})">CAP</button></td> function openmodal(id) { // AJAX请求获取状态 $.get("<?php echo base_url('Main/getStatus'); ?>", { id: id }) .done(function(data) { if (data) { const newtime = new clock() let BeforeInspectedDate; if(data[0].BeforeInspectedDate != null){ BeforeInspectedDate = data[0].BeforeInspectedDate.split(' ')[0] } else { BeforeInspectedDate = newtime.getCurrentTime(); } document.getElementById('bdate').value = BeforeInspectedDate console.log(document.getElementById('bdate').value) } }) };
问题根源
直接传递参数时,模板字符串拼接会将null/undefined转成字符串"null"/"undefined",导致!BeforeInspectedDate判断失效——因为"null"是长度为4的非空字符串,逻辑非运算结果为false,永远走else分支。而二次请求时,从后端返回的data中取到的是原始的null/undefined值,空值判断能准确识别。
解决方案
方案1:修正模板字符串的参数传递
用JSON.stringify处理可能为空的参数,避免被转成字符串形式的"null":
// 在renderQuestions的循环中修改按钮拼接代码 html += ` <tr class="tablerows"> <td><button class="btn btn-icon btn-primary" onclick="openmodal(${JSON.stringify(response[i].BeforeInspectedDate)})">CAP</button></td> </tr> `;
方案2:兼容字符串化的空值判断
修改openmodal函数的判断逻辑,处理字符串形式的"null"/"undefined":
function openmodal(BeforeInspectedDate) { let beforedate = document.getElementById('bdate') const newtime = new clock() // 先处理字符串化的空值情况 if (['null', 'undefined', '', null, undefined].includes(BeforeInspectedDate)) { beforedate.value = newtime.getCurrentTime(); } else { let newbeforedate = BeforeInspectedDate.split(' ')[0] beforedate.value = newbeforedate; // 修复原代码中的笔误 } }
方案3:推荐使用事件委托(避免内联onclick)
彻底避免模板字符串拼接参数的问题,用事件委托绑定点击事件:
// renderQuestions中给按钮添加自定义属性存储日期 html += ` <tr class="tablerows"> <td><button class="btn btn-icon btn-primary cap-btn" data-date="${response[i].BeforeInspectedDate ?? ''}">CAP</button></td> </tr> `; // 页面加载完成后绑定事件委托 document.addEventListener('DOMContentLoaded', function() { document.body.addEventListener('click', function(e) { if (e.target.matches('.cap-btn')) { const BeforeInspectedDate = e.target.dataset.date; let beforedate = document.getElementById('bdate') const newtime = new clock() if (!BeforeInspectedDate) { beforedate.value = newtime.getCurrentTime(); } else { let newbeforedate = BeforeInspectedDate.split(' ')[0] beforedate.value = newbeforedate; } } }); });
内容的提问来源于stack exchange,提问作者Taha
相关产品推荐
相关产品推荐

