JS中的闭包

要想了解闭包,我们就必须首先了解JS中的函数
因为在JS中函数是一等公民
一等公民的意思就是函数的使用是十分灵活的
函数可以作为另外一个函数的参数,也可以作为另外一个函数的返回值来使用。

JS中的闭包的定义:

JS中的一个函数,如果访问了外层作用域的变量,那么他就是一个闭包

闭包产生的三个必要条件

  • 函数的嵌套
  • 内部函数体内存在访问外部函数体定义的局部变量
  • 外部函数被调用

例如

function outer() {
	//外部函数定义的局部变量
	let foo = 10; 
	let bar = 100;
	
	function inner1() {
		console.log('Hello World');//内部函数没有访问外部函数定义的任何变量,不形成闭包
 	}
 	
	function inner2() {
		foo ++; //使用了外部函数定义的变量,形成闭包
		console.log(foo);
	 }
	 
	function inner3(bar) {
		bar --; //内部函数参数表中存在和外部函数定义变量的同名参数,参数表优先级高,不形成闭包
		console.log(bar);
     }
     
}
outer();

闭包的作用及生命周期

// 借助闭包
function outer() {
	let foo = 10;
	function inner() {
		foo ++;
		console.log(foo);
 	}
	return inner; //将闭包return到全局
}
let fn = outer();
//不借助闭包
function outer() {
	let foo = 10;
	foo++;
	return foo;
}
console.log(outer()); 11
console.log(outer()); 11

//原本代码运行到这一行时,局部变量foo内存已经被回收,但因为形成了闭包,局部变量foo将继续存在
fn(); //foo => 11
fn(); //foo => 12
局部变量的生命周期由跟随外部函数结束改为跟随闭包结束,换言之,局部变量的生命周期被延长了
允许在函数的外部借助闭包访问函数内的局部变量,但全局环境依然无法直接操作局部变量
闭包在外部函数调用完毕后,栈内存中的闭包名称立即释放
如果闭包没有被return到全局,则栈内存中的函数对象也被立即释放
如果闭包被return到全局,则闭包堆内存中的函数对象会保留至整个javascript程序结束

//程序运行至此行内部函数inner由于被return到全局,所以会一直存在
// 所以我们如果我们要防止内存泄漏,需要手动结束闭包的生命周期
fn = null; 

内存泄漏的案例

function createFnArray() {
	// 一个整数在内存中占据4个字节,1024字节等于1kb,1024kb等于1mb
	// 所在该数组占据的空间是4M
	var arr = new Array(1024 * 1024).fill(1);
	return function () {
		console.log(arr.length);
	};
}

var arrayFn = createFnArray();
// arrayFn = null

在此处 如果我们不将arrayFn设为空,也不使用arrayFn,那么就会白白浪费掉4MB的内存空间,造成内存泄漏

应用实例:

//利用函数定义一个模块
function Foo() {
	//定义不希望模块外部直接访问的变量
	let name = 'tom';
	let age = 10;
	let alive = true;
	
	function grow() {
		age ++; //长大一岁
 	}
 	
	function kill() {
		alive = false; //去世
 	}
 	
return {
	grow: grow,
	kill: kill,
 	}
}
//利用闭包
let foo = Foo();
foo.grow(); //age 自增
foo.kill(); //弄死Foo,但遗体尚在
foo = null; //灰飞烟灭,尸骨无存
posted @   w灰二  阅读(208)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示