作为一个前端开发者,闭包是必须要攻克掉的障碍。据说好多面试者挂在闭包面试上。下面我就给大家讲一下我理解中的闭包。不说太多的废话,直接进入主题。
变量作用域
学习编程语言需要明白,变量的作用域。变量作用域分全局变量、局部变量。全局变量尽量少用,因为它很耗费性能。简单理解,全局变量:在任何一个地方都可以访问到。局部变量只有在局部才可以访问到。先举个例子看看:
var data=100; function domo(){ var data1=20; console.log(data); console.log(data1); } domo();
可以看出data在dome中也可被访问。所有呢!data是全局变量,data1是局部变量。
闭包
1.常见闭包
/** * 最简单的闭包 * */ function bibao(){ var d=10; return function(){ console.log(d); d++; } } var _bibao=bibao(); _bibao();//输出10 _bibao();//输出11
首先我们要明白函数是有返回值的,如果不手动更改返回值则返回undefined。如何手动更改返回值?就是在函数中使用return 返回。可以返回为布尔值也可以是对象也可以是空字符串也可以是函数。这个最简单的闭包就是返回一个匿名函数。_bibao接收到bibao函数的返回。相当于_bibao===function(){console.log(d);d++;}。然而这个匿名函数中用到了d。此刻_bibao就可以访问d;也可以更改d
2.无return闭包
-
/** * 无return的闭包 * * */ var _bibao1; function bibao1(){ var d=20; _bibao1= function(){ console.log(d); d++; } } bibao1(); _bibao1();//输出20
_bibao1();//输出21
这种没有return 的闭包其实跟上面最简单的闭包是相同的,它只不过把一个匿名函数赋值给全局变量。全局变量此刻保持对这个匿名函数的引用。当调用_bibao1()的时候,就等于调用这个匿名函数。
3.回掉函数中产生的闭包
/** * 回掉函数中产生的闭包 * @callback {Function} 回掉函数 * */ function bibao2(callback){ var d=100; setTimeout(function(){ callback() },2000) } function _bibao2(){ var d=120; bibao2(function(){ console.log(d); d++; }); setTimeout(function(){ console.log(d); },3000) } _bibao2();//两秒后输出120。三秒后输出121
只有记住一个变量或者参数是一个函数的引用,这个答案就会迎刃而解。执行_bibao2();它会执行bibao2,然后传入一个匿名函数,此刻这个匿名函数保持可以访问到_bibao2中的d。bibao2中的参数callback保持对这个匿名函数的引用。所以它访问的是_bibao2中的d而不是bibao2中的d。
总结
闭包是很有用的,也是很常用的,只有我们记住了它的原理,就能够掌控它们。它只不过是一个函数的引用,这个函数可以访问到这个函数的父函数中的变量而已。