闭包的初步认识

96 阅读2分钟

闭包


概念:闭包就是函数能够记住并访问它的词法作用域,即使当这个函数在它的词法作用域之外执行时。简单来说就是在函数的外部可以使用到其内部的变量,可以将该函数理解为一个闭包。

function foo() {
	var a = 2;

	function bar() {
		console.log( a );
	}

	return bar;
}

var baz = foo();

baz(); // 2  看到闭包了,妈妈

原理:js中的变量,函数在执行的时候都会被加载到栈中,执行完毕弹出,当使用闭包的时候,函数执行完成后,不会弹出,因为其他的地方还要加载其内部变量

闭包的特点

  • 闭包的变量不能及时被释放,一直存在即占用空间,造成内存泄漏

  • 可以形成私有变量,只能被特定的函数使用,避免变量污染

    解释一下内存泄漏: 存在一些无法访问的变量或对象,它们占用的内存却无法被回收。这会导致应用长期运行后内存占用越来越高,甚至导致应用崩溃。

闭包+循环


展示闭包怎么能少的了for循环。

for (var i=1; i<=5; i++) {
   setTimeout( function fn(){
   	console.log( i );
   }, i*1000 );
}

这段代码的含义是,我们希望他每秒打印一次i,并且i为1,2,3..5,但实际上你运行这段代码,会得到5次被打印的“6”。

首先解释一下6从哪里来的,6为for循环的终止条件,也就是说for循环走完时的最终值。实际上这里和时间没有关系,即使你改成0ms也是一样的结果。

那么,怎么让他按预期执行呢?不难发现i变量在回调函数内部没有被保存下来,那么我们就要想办法将其存下来,可以使用立即执行函数。

let's go~

for (let i = 1; i <= 5; i++) {            
            setTimeout(function timer() {
                console.log(i);
            }, i  * 1000);
        }

我们这里使用了ES6新语法let,创建了一个块级作用域,使得变量i得以保存下来。

泰酷辣~块级作用域和闭包携手工作,解决世界上所有的问题。我不知道你怎么样,但这使我成了一个快乐的 JavaScript 开发者。