如何避免JSHint警告:循环内函数引用外部作用域变量语义混乱问题
解决JSHint循环内函数引用外层变量的警告问题
警告产生的原因
你在for循环内部定义事件回调函数时,回调引用了外层作用域的循环索引i或者元素集合变量,JSHint默认会提示该写法可能存在语义歧义。即使你用了let声明i(ES6中let在for循环中每次迭代会生成独立块级作用域,实际运行不会出错),仍然会触发该校验规则。
第一种场景(suggestionIcon鼠标事件)的解决方案
方案1:用forEach遍历替代for循环(最简便)
直接遍历元素集合,每个迭代的元素变量独立存在于当前作用域,不会触发警告:
// 低版本浏览器可先转数组再遍历:Array.from(suggestionIcon).forEach(...) suggestionIcon.forEach(function(iconEl) { iconEl.addEventListener('mouseenter', function() { iconEl.classList.remove('suggestion-before'); iconEl.classList.add('suggestion-after'); }); });
方案2:使用this指向当前触发元素(不修改循环结构)
事件回调中的this默认指向绑定事件的DOM元素,无需引用外层的i和集合变量:
for (let i = 0; i < suggestionIcon.length; i++) { suggestionIcon[i].addEventListener('mouseenter', function () { // this就是当前触发事件的图标元素 this.classList.remove('suggestion-before'); this.classList.add('suggestion-after'); }); }
方案3:事件委托(性能最优,适合元素数量多的场景)
直接将事件绑定到父元素,不需要循环绑定每个子元素:
document.querySelector('.search-suggestion').addEventListener('mouseenter', function(e) { const targetIcon = e.target.closest('.suggestion-icon'); if (!targetIcon) return; targetIcon.classList.remove('suggestion-before'); targetIcon.classList.add('suggestion-after'); }, true); // 开启捕获阶段触发,匹配mouseenter事件的行为特性
第二种场景(openSubscribe点击事件)的解决方案
同样可以用上述的forEach或者this方案,这里给出forEach示例:
openSubscribe.forEach(function(btn) { btn.addEventListener('click', function() { if(contactDiv.classList.contains('hide')){ subscribe.classList.remove('hide'); }else{ alert("请先关闭联系表单"); } }); });
内容的提问来源于stack exchange,提问作者jak_es
相关产品推荐
相关产品推荐

