闭包是一个什么概念,之前有人会说一个函数返回一个函数,这就是闭包,真的只有返回函数才叫闭包么?这只是面子上的东西,只看到形式上的东西,并没有抓住本质。
高阶函数是一个和闭包密不可分的的概念,之后你慢慢会发现。
闭包
说到闭包,离不开两个概念,变量作用域和变量生命周期。
1. 变量作用域
变量在其定义的时候,作用域的范围也就确定了。全局变量在任何位置都可以访问。局部变量只能函数内部访问。在函数中访问变量,如果内部找不到,会依次沿着作用域链从内到外搜索。
2. 变量生命周期
全局变量的生命周期是永久的,局部变量会在函数执行完之后被销毁。闭包的作用就是延续了局部变量的生命周期。
很经典的一个例子:
|
|
利用闭包的特点,经常用了实现全局变量私有化和变量生命周期延续。
全局变量私有化
123456var sum = (function() {var result = 0;return function(a) {return result += a;}})()变量生命周期延续
12345678var report = (function() {var images = [];return function(src) {var img = new Image()images.push(img)img.src = src;}})()
像上面例子中的变量result和images,对于他们内部返回的函数来说,他们就是自由变量,既不是参数又不是内部变量,而且他的生命周期与内部函数一致,即使创建环境消失也不例外,这种形式就叫做闭包。
高阶函数
至少满足以下一个条件的函数就可以成为高阶函数。
函数可以作为参数传递。
函数可以作为返回值输出。
这么看来,闭包是不是和高阶函数密不可分呢。
1. 函数作为参数
运用的方面很多,最典型的情况就是回调函数。实际上我们就是将可变的逻辑代码部分从不变的部分抽离出来,这样我们的代码就可以非常灵活,满足不同的需求。比方说Array.prototype.sort,我们通过回调函数将我们的排序具体实现告诉数组,分分钟钟实现多种排序效果。
2. 函数作为返回值输出
让函数返回一个可执行的函数,那这个操作就可以延续下去,常常用在函数包装上面。
下面是一个包装resize函数的方法,由于resize触发很频繁,因此通过setTimeout进行节流控制。
|
|
总结
闭包和高阶函数是设计模式的基础,通过闭合和高阶函数的组合实现多种设计模式,之后遇到再做介绍。