JavaScript闭包原理与使用详解

作者:异步漫步时间:2026-10-25 21:51:27浏览:114

本文深入解析JavaScript闭包的形成原理,涵盖变量作用域提升、生命周期管理及词法环境引用机制。通过按钮点击案例演示闭包解决循环变量共享问题的方法,并介绍利用闭包实现私有变量保护及函数节流等实际应用场景。

1. 理解闭包

闭包的一个典型应用案例:利用 for 循环为前述五个按钮绑定点击事件。

    <button type="button" class='button'>按钮</button>
    <button type="button" class='button'>按钮</button>
	<button type="button" class='button'>按钮</button>
	<button type="button" class='button'>按钮</button>
	<button type="button" class='button'>按钮</button>
    var buttons = document.getElementsByClassName('button');
			for (var i = 0; i < 5; i++) {
				buttons[i].onclick = function() {
					console.log(i+1);
				}
			}

若直接点击这五个按钮,控制台均输出数字 5,此现象源于变量 i 的作用域机制导致代码未按预期执行。

通过引入闭包机制对原有代码进行优化。

var buttons = document.getElementsByClassName('button');
			for (var i = 0; i < 5; i++) {
				buttons[i].onclick = (function(i){
					return function(){
						console.log(i+1);
					}
				}(i))
			}

再次点击这五个按钮,控制台将依次显示数字 1、2、3、4、5。

2. 变量作用域与生命周期解析

2.1 变量作用域定义

  • 作用域指的是变量在代码中可被访问的有效范围。
  • 采用 var 关键字声明的变量存在提升现象至全局,而函数内部声明的变量仅限在函数体内访问。
  • 采用 let 和 const 关键字声明的变量不具备提升特性。

在前述代码示例中,for 循环内的变量 i 由 var 声明,从而提升至全局作用域。由于在按钮点击事件触发前 for 循环已执行完毕,最终打印出的均为全局变量 i 的值,即数字 5。

在利用闭包进行代码优化时,通过立即执行函数(IIFE)将每次循环的变量 i 封闭在函数内部,从而确保最终输出结果为正确值。

2.2 变量生命周期

全局作用域内的变量生命周期为永久存在,而函数内部的变量在函数执行结束后即被回收并销毁。

当形成闭包时,由于函数的返回值(即另一个函数)依然引用着原函数的局部变量,这导致即使原函数执行完毕,其内部变量依然存在于内存中。闭包正是基于这一特性发挥作用。

3. 闭包定义及其功能

3.1 闭包定义

基于前述分析可知,闭包核心涉及变量的生命周期与作用域概念。构建闭包需同时满足以下三个必要条件:

  • 函数的返回值必须是一个函数。
  • 被返回的函数内部引用了外层函数的局部变量。
  • 被返回的函数在外部作用域中被调用。

3.2 闭包的实际应用场景

3.2.1 实现私有变量存储

JavaScript 语言原生不提供 private 关键字,但可以通过闭包机制将变量封装在函数内部,以此达到保护变量不被外部直接访问的目的。

	var getUserInfo = (function() {
		var userInfo = {
			name: 'ian',
			age: 21
		};
		return function() {
			return userInfo;
		}
	}());
	console.log(getUserInfo()); //{name:'ian',age:21}
	console.log(userInfo); //Uncaught ReferenceError: userInfo is not defined

3.2.2 利用闭包实现节流函数

	function throttle(fn,delay){
			var timer=null;
		  return function(){
			  if(!timer){
				  timer=setTimeout(()=>{
				  	fn();
					timer =null;
				  },delay)
			  }
		  }
		}
		window.onresize= throttle(function(){
			console.log('resize')
		},500)

至此,关于 JavaScript 闭包原理与应用的介绍已告一段落。如需了解更多 JS 闭包相关内容,请查阅本站历史文章或继续浏览后续相关文章,感谢大家对本站的支持!

作者最新文章