JavaScript中全局声明的变量one为何会出现值丢失的问题?
问题原因
你的变量one并没有丢失,本质是代码执行时序的问题,赋值操作的执行时机晚于你打印/调用变量的时机:
- 全局作用域声明
let one时,变量默认初始值为undefined ready函数在DOM加载完成后同步执行:首先给按钮注册click事件监听,这个事件的回调函数只有用户点击按钮时才会触发,不会在ready执行阶段运行ready函数同步执行到console.log(one)时,你还没有点击过按钮,one从来没有被赋值,因此输出undefined- 只有当你点击按钮触发回调后,才会执行
one = document.getElementById("red")的赋值操作,这时候回调内部的console.log(one)才能打印出正确的DOM元素
你注释掉的one.addEventListener报错也是同理:ready同步执行时one还是undefined,调用方法自然会抛出异常。
解决方法
有两种常见的修复方案:
方案1:在元素创建后绑定事件
把mouseover的绑定逻辑放到click回调里,one赋值完成后再执行:
function check() { document.addEventListener("DOMContentLoaded", ready); } let one; function ready() { let button = document.getElementById("transform"); let div = document.getElementById("objectImg"); let img = document.getElementById("dog"); button.addEventListener("click", function(a) { if (img) { img.parentNode.removeChild(img); div.innerHTML = "<img id = 'red' src = 'img/cat.jpg'>"; one = document.getElementById("red"); // 赋值完成后再绑定事件 one.addEventListener("mouseover", (a) => { // 你的业务逻辑 }); img = false; console.log(one); } else { alert("some text"); } }); } check();
方案2:使用事件委托
直接给父元素绑定事件,不需要等子元素创建即可生效:
function check() { document.addEventListener("DOMContentLoaded", ready); } function ready() { let button = document.getElementById("transform"); let div = document.getElementById("objectImg"); let img = document.getElementById("dog"); // 给父元素div绑定mouseover事件,委托判断目标元素 div.addEventListener("mouseover", (e) => { if(e.target.id === 'red') { // 你的业务逻辑 } }); button.addEventListener("click", function(a) { if (img) { img.parentNode.removeChild(img); div.innerHTML = "<img id = 'red' src = 'img/cat.jpg'>"; img = false; } else { alert("some text"); } }); } check();
内容的提问来源于stack exchange,提问作者Sherlock1996
相关产品推荐
相关产品推荐

