javaScript里的闭包到底是什么?该怎么理解?

关于javaScript里的闭包问题,看了很多答案都不甚理解,在这里我谈谈我理解里的闭包。
在理解闭包是什么之前我需要先理解什么是作用域。

全局作用域

打开一个 js ,随便写了一行代码,这行代码所在的位置就会是全局作用域(global scope)。比如:

var i =1;//全局作用域在代码任何位置都可以使用,一篇代码只有一个全局作用域

局部作用域

全局作用域只有一个,在全局使用域里面定义的其它的作用域都被称为局部作用域(local scope)。局部作用域是由函数创建的,每个函数都会创建一个局部作用域。

// 作用域 A: 全局作用域(位于函数外部)
var nameA = "全局作用域"

var a = function() {
  // 作用域 B:局部作用域(在函数内部)
  // 这里是的局部作用域是由函数a创建的 

  var nameB = '局部作用域'
}

在这个局部作用域里面定义的东西,在这个作用域的外面是访问不到的。试一下:

var nameA = "全局作用域"
var a = function() {
  var nameB = '局部作用域'
}
console.log(nameA)
// 返回:全局作用域
console.log(nameB)
//返回:undefined

闭包

了解了作用域接下来我讲一讲闭包

定义

维基百科:在计算机科学中,闭包(Closure),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。

上面的定义看的有点懵,那我说说我的看法:在我看来,不是说能够访问到其他作用域的变量就是闭包,这是很笼统的。准确来说,闭包是基于正常的垃圾回收处理机制下的。也就是说,一般情况一个函数(函数作用域)执行完毕,里面声明的变量会全部释放,被垃圾回收器回收。但闭包利用一个技巧,让作用域里面的变量,在函数执行完之后依旧保存没有被垃圾回收处理掉。

还是有点懵?那贴上一段代码来看看:

function fn(x) {
    var a = 3;
    return function (y) {
        alert(x + y + (++a));
    }
}
var bar = fn(2); // bar 现在是一个闭包
bar(10);

我们来看看这段代码,我们声明了一个函数fn,在到var bar = fn(2)开始执行函fn(2),由于只传入一个参数2,所以执行到return function(y)这一行代码会停下等参数y传入,但是这个时候我们想想a变量和参数回收了吗?其实并没有,因为return function(y)这一行代码还未执行,还在等待参数y传入。f n的变量并没有被释放,在return在等待继续使用这些变量了,这个时候bar就是一个闭包。这时候在看看维基百科的解释是不是有些明白了?

闭包的缺点

1 因为闭包的变量保存在内存中,内存泄漏,对内存的消耗很大,所以不要滥用闭包

闭包常用的地方:
1 es5 for循环事件监听
2 函数里使用了定时器
3 封装许多高级的功能集
减少闭包使用可以用立即执行函数传递变量

参考:https://www.cnblogs.com/JIANGCHEN520/p/7118656.html

你可能感兴趣的:(JS)