Pixiv - KiraraShss
796 字
4 分钟
函数闭包
欢迎来到我的博客!
使用 Markdown 格式编写。
什么是闭包?
闭包是指一个函数能够访问并记住其词法作用域中的变量,即使该函数在其词法作用域之外执行。
您代码中的闭包实例
在useDog.ts中,getDog函数就是一个典型的闭包:
export default function (){ // 外部作用域的变量 let dogList = reactive([ 'https://images.dog.ceo/breeds/pembroke/n02113023_4373.jpg' ])
// 闭包函数 - 可以访问外部作用域的dogList async function getDog(){ try { let result = await axios.get('https://dog.ceo/api/breed/pembroke/images/random') dogList.push(result.data.message) // 访问外部变量 } catch (error) { alert(error) } }
return {dogList, getDog} // 返回闭包函数}闭包的核心特性
1. 词法作用域访问
function outer() { let count = 0; // 外部变量
function inner() { count++; // 内部函数可以访问外部变量 console.log(count); }
return inner;}
const closure = outer();closure(); // 1closure(); // 2 - 闭包记住了count的值2. 变量持久化
function createCounter() { let count = 0;
return function() { count++; return count; };}
const counter1 = createCounter();const counter2 = createCounter();
console.log(counter1()); // 1console.log(counter1()); // 2console.log(counter2()); // 1 - 每个闭包有自己的作用域Vue 3组合式API中的闭包应用
1. 自定义Hooks(如您的useDog)
export function useCounter() { const count = ref(0);
function increment() { count.value++; // 闭包访问count }
function reset() { count.value = 0; // 闭包访问count }
return { count, increment, reset };}
// 组件中使用const { count, increment } = useCounter();2. 事件处理器的闭包
<script setup>const message = ref('Hello');
// 闭包:setTimeout回调函数可以访问messagefunction delayedAlert() { setTimeout(() => { alert(message.value); // 访问外部作用域的message }, 1000);}</script>闭包的常见应用场景
1. 数据封装
function createPerson(name) { let age = 0; // 私有变量
return { getName: () => name, getAge: () => age, setAge: (newAge) => age = newAge, celebrateBirthday: () => age++ };}
const person = createPerson('张三');person.setAge(25);person.celebrateBirthday(); // age变为262. 防抖函数
function debounce(fn, delay) { let timer = null; // 闭包保存timer
return function(...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); };}
const debouncedSearch = debounce(search, 300);3. 模块模式
const myModule = (function() { let privateVar = 0;
function privateMethod() { return privateVar; }
return { publicMethod: function() { return privateMethod(); } };})();闭包的内存管理
优点:
- 数据封装:创建私有变量
- 状态保持:函数调用间保持状态
- 模块化:实现模块模式
注意事项:
- 内存泄漏:闭包会阻止垃圾回收器回收外部变量
- 性能考虑:过度使用闭包可能影响性能
在Vue中的最佳实践
<script setup>// 好的实践:使用响应式refconst count = ref(0);
function increment() { count.value++; // 闭包访问响应式数据}
// 避免的实践:直接在闭包中修改DOMfunction badPractice() { setTimeout(() => { // 避免:直接操作DOM,应该使用响应式数据 document.getElementById('counter').textContent = count.value; }, 1000);}</script>总结
闭包是JavaScript中非常重要的概念,它让函数能够:
- 记住其创建时的词法环境
- 访问外部作用域的变量
- 保持状态在多次调用之间
在Vue 3的组合式API中,闭包被广泛应用于自定义Hooks、事件处理等场景,是实现组件逻辑复用的关键技术。
您提供的useDog.ts就是一个完美的闭包应用实例!
赞助支持
如果这篇文章对你有帮助,欢迎赞助支持!
最后更新于 2026-04-28,距今已过 126 天
部分内容可能已过时