JavaScript 中的閉包和事件委托
包 (Closures)
閉包是 JavaScript 中一個非常強大的特性,它允許函數(shù)訪問其外部作用域中的變量,即使在該函數(shù)被調(diào)用時,外部作用域已經(jīng)執(zhí)行完畢。閉包可以幫助我們實現(xiàn)數(shù)據(jù)的私有化、封裝和模塊化,使代碼更簡潔、易讀和可維護。
閉包的定義
簡單來說,閉包是指有權(quán)訪問另一個函數(shù)作用域中變量的函數(shù)。
function outerFunction() { let outerVariable = "I am outside!"; function innerFunction() { console.log(outerVariable); // innerFunction 可以訪問 outerVariable } return innerFunction; } const closure = outerFunction(); closure(); // 輸出: I am outside!
在上述例子中,innerFunction 就是一個閉包,它可以訪問 outerFunction 中的 outerVariable,即使 outerFunction 已經(jīng)執(zhí)行完畢。
閉包的應(yīng)用
- 數(shù)據(jù)私有化:
function createCounter() { let count = 0; return function() { count++; return count; }; } const counter = createCounter(); console.log(counter()); // 輸出: 1 console.log(counter()); // 輸出: 2 console.log(counter()); // 輸出: 3
在這個例子中,count 變量被封裝在 createCounter 函數(shù)的作用域內(nèi),只能通過返回的閉包函數(shù)進行訪問和修改。
- 模擬塊級作用域:
在 ES6 之前,JavaScript 沒有塊級作用域,我們可以使用閉包來模擬塊級作用域。
for (var i = 1; i <= 3; i++) { (function(i) { setTimeout(function() { console.log(i); }, i * 1000); })(i); } // 輸出: 1, 2, 3 (每隔一秒輸出一個數(shù)字)
通過立即執(zhí)行函數(shù)表達式 (IIFE),為每次循環(huán)創(chuàng)建了一個新的作用域,從而使 setTimeout 中的 i 保持正確的值。
事件委托 (Event Delegation)
事件委托是一種利用事件冒泡機制,將事件監(jiān)聽器添加到父元素上,從而管理多個子元素事件處理的一種技術(shù)。它可以減少內(nèi)存占用,提高性能,特別是在需要處理大量動態(tài)生成的子元素事件時非常有用。
事件委托的定義
通過將事件監(jiān)聽器添加到父元素上,當(dāng)子元素的事件被觸發(fā)時,事件會冒泡到父元素,由父元素的事件監(jiān)聽器進行處理。
<ul id="parent"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul>
document.getElementById('parent').addEventListener('click', function(event) { if (event.target.tagName === 'LI') { console.log(event.target.innerText); // 輸出點擊的列表項的文本 } });
在這個例子中,我們只為 ul 元素添加了一個點擊事件監(jiān)聽器,但可以處理所有 li 元素的點擊事件。
事件委托的應(yīng)用
- 動態(tài)內(nèi)容:
當(dāng)頁面上有大量動態(tài)生成的元素時,使用事件委托可以簡化事件處理。
const list = document.getElementById('parent'); document.getElementById('addItem').addEventListener('click', function() { const newItem = document.createElement('li'); newItem.innerText = `Item ${list.children.length + 1}`; list.appendChild(newItem); });
- 提高性能:
當(dāng)需要為大量元素添加事件監(jiān)聽器時,事件委托可以顯著提高性能,因為只需要為父元素添加一個事件監(jiān)聽器,而不是為每個子元素添加。
<button id="addItem">Add Item</button> <ul id="parent"> <!-- 動態(tài)生成的列表項 --> </ul>
總結(jié)
閉包能夠訪問外部函數(shù)作用域中的變量,從而實現(xiàn)數(shù)據(jù)私有化和封裝;
事件委托利用事件冒泡機制,通過將事件監(jiān)聽器添加到父元素上,簡化了事件處理,提高了性能。

浙公網(wǎng)安備 33010602011771號