JavaScript踩坑笔记09---闭包、回调函数

闭包:

简单点说,闭包就是一个仓库,它的作用就是将我们要用的局部变量暂时储存起来。
举例说明。

// 定义一个函数fn,其中有一个局部变量num
function fn() {
	var num = 10;
}

以上例子中,我们在函数fn中定义了一个变量num,所以变量的num的作用域就局限在函数fn内部。
那么问题来了,如何在其他作用域下获取该变量?
很简单,我们只需要使用return关键字返回就可以了。

// 定义一个函数fn,其中有一个局部变量num
function fn() {
	var num = 10;
	return num;
}
console.log(fn()); // 10

可是这种方式有一个缺点,外部可以直接获取该变量。
问题又来了,我又想获取这个局部变量,又希望能够修改这个局部变量,并且我对这个局部变量还有一系列乱七八糟的操作,我该如何实现?
所以就有了闭包,举例说明。

// 定义一个函数fn,其中有一个局部变量num
var fn = function () {
	var num = 10;

	return {
		// 获取变量
		getNum: function () {
			return num;
		},
		// 修改变量
		setNum: function (newNum) {
			num = newNum;
		}
		// 还可以接着定义一些对变量num乱七八糟的操作
	};
};

var aaa = fn();

aaa.setNum(100);
console.log(aaa.getNum()); // 100

以上例子中,return返回了一个对象,对象里定义了一些方法,这些方法就是我们所说的闭包,我们通过闭包,将局部变量num暂时储存了起来,并且外部无法直接获取变量num。
闭包的作用就是将私有变量,封装在一个安全的环境中,外部无法直接访问。
但是闭包有一个很大缺点,也是闭包的优点,暂时储存。
一般来说,一个函数被调用结束后,会销毁他的执行上下文,这样做的目的是节省资源。
但是闭包不一样,拿上述例子来说,函数fn返回了一个对象,这个对象里包含了两个函数,这两个函数分别创建了两个作用域,而在这两个作用域中,又引用了父级作用域的自由变量,所以,一旦销毁函数fn的执行上下文,那么它闭包中的引用的自由变量也会被销毁,结果导致程序报错。所以闭包正是通过这种方式,将变量num给暂时存储了起来,这正是闭包的优点,同时,这也是闭包的缺点,大量的使用闭包会增加资源的消耗。
闭包一般有两种表现形式。

  1. 闭包作为函数返回值。
  2. 闭包作为函数的参数。

上述例子正是闭包的第一种表现形式,也是常见的一种形式。第二种表现形式,我们称之为回调。

回调函数:

回调函数,顾名思义,回头调用的函数,也就是说该函数是在一定的条件下调用的。
举例说明。

// 定义主函数parentFunction
function parentFunction(fn) {
	console.log("主函数开始执行...");
	// 函数fn作为参数被传入主函数,并在主函数内执行
	fn();
	console.log("主函数执行完毕...");
}

// 此时函数callbackFunction为parentFunction的回调函数
var callbackFunction = function () {
	console.log("回调函数开始执行...");
};

parentFunction(callbackFunction);
// 主函数开始执行...
// 回调函数开始执行...
// 主函数执行完毕...

回调函数作为参数,传入主函数内,并在主函数内的某一点执行,就好比是主函数内定义了这个回调函数,所以回调函数的本质也是闭包。
回调函数的实际应用:

  1. 决定权交给客户端
  2. 与客户端进行交互

个人学习总结,欢迎批评指正

猜你喜欢

转载自blog.csdn.net/qq_43738157/article/details/84564225