这与其说是编码挑战,不如说是思维挑战 🤓
以下面的 IIFE 为例,在函数的末尾附加一个事件侦听器,每次单击 BODY 元素时,该侦听器都会将所选 h1 元素(“标头”)的颜色更改为蓝色。不要再次选择 h1 元素!
现在向你自己(或你周围的人)解释为什么这有效!花所有你需要的时间。想想回调函数的确切执行时间,以及这对本例中涉及的变量意味着什么。
祝你好运 😀
初始代码
(function () {
const header = document.querySelector('h1');
header.style.color = 'red';
document.querySelector('body').addEventListener('click', function () {
header.style.color = 'blue';
});
})();
这段代码是一个立即执行函数表达式(Immediately Invoked Function Expression,IIFE),它包含了两部分操作:
1. 首先,通过 document.querySelector('h1') 获取页面中第一个 <h1> 元素,并将其赋值给变量 header。
2. 然后,将 <h1> 元素的文字颜色设置为红色('red')。
接着,添加了一个事件监听器,当用户点击页面任意位置时,会触发事件回调函数,将 <h1> 元素的文字颜色改为蓝色('blue')。
整个操作在一个 IIFE 中进行,这样可以避免污染全局作用域,确保代码中的变量不会影响到全局环境。
在这段代码中,回调函数可以访问到 header 变量是因为 JavaScript 中的闭包机制。闭包是指函数和其周围状态(词法环境)的组合,这意味着函数可以访问其外部函数作用域中的变量,即使外部函数已经执行完毕。
在这里,事件监听器的回调函数是一个闭包,它可以访问到包含它的外部函数的作用域,也就是立即执行函数表达式中的作用域。因此,回调函数可以访问并操作在立即执行函数中定义的 header 变量,实现了改变 <h1> 元素文字颜色的效果。
总结起来,闭包使得内部函数可以访问外部函数的作用域中的变量,从而实现了跨作用域的数据共享和操作。