javascript闭包机制

定义

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

从开始学习JavaScript开始就开始接触闭包,到开始工作对闭包的理解一直懵懵懂懂,查询各种文档和大牛的分析(都没看懂,哈哈,可能说的太深奥了),对闭包的解释有很多种

闭包可以定义私有变量,避免被意外修改
闭包可以避免变量被回收
闭包可以避免全局变量污染
还有人说你写得每个方法都是一个闭包

看了很多解释,每次都觉得自己理解了,其实都不太理解,而是理解了一部分(当然可能到现在对闭包的理解还是不全面,以后还要多多学习)

其实上面说的都是闭包的用法,闭包可以解决这些问题,所以我们觉得很奇怪,理解不了

首先拿一个很经典的例子 计数器

//第一种写法(全局变量法)
var count = 0
function add() {
    return ++count
}
add() // 1
add() // 2
add() // 3

// 第二种写法(闭包法)
var add = (function add() {
    var count = 0
    return function() {
        return  ++count
    }
})()
add() // 1
add() // 2
add() // 3

这就是一个闭包

那么上面两种计数器的写法有什么区别呢,

第一种全局count是全局变量,会造成全局变量污染(当业务需求有很多需要用这种方法实现的时候,会定义很多全局变量才行);而第二种不存在这种问题
第一种count因为是全局变量,谁都可以修改,会导致无法追溯到底谁改变了他,或者可能会被意外改变,很难维护
都是计数器,功能一样,实现方式不同

那么说到现在,什么才是闭包呢

闭包可以定义私有变量,避免被意外修改

经过上面的例子我们可以看到,我们可以直接访问到count或者修改count的值么,显而易见不能,我们仅仅是获得了经过(包含)count的计算返回值而已,所以在这里(闭包)就有了私有变量的概念

闭包可以避免变量被回收

这里牵扯到JavaScript的垃圾回收机制(不晓得的同学可以移步去看看js的垃圾回收)。js有两种情况会被当成垃圾回收掉

当变量没有被引用的时候,就会被回收
当变量被循环引用,没有被其他引用(其实就是一个闭环引用)时,也会被垃圾回收掉

而在闭包中,count一直在被内层函数引用,无法释放,所以就无法被垃圾回收(看到这里有同学可能会说,那大量的闭包会不会造成内存泄漏 @_@ ,想了解更深层次,可以继续探讨哦,在这里就不详解喽)

闭包可以避免全局变量污染

答案显而易见,闭包是闭环,变量都定义在函数内,且不引用任何外部函数

还有人说你写得每个方法都是一个闭包

这个解释不知道大家理解不,如果这句话成立,嘿嘿。那么我们看看第一种《计数器》的实现方式

//第一种写法(全局变量法)
var count = 0
function add() {
    return ++count
}
add() // 1
add() // 2
add() // 3

这也是闭包,那你这不模棱两可,前后不搭么?不是的,这也是闭包,可以这么理解,但是我们也可以不叫他闭包。叫他闭包是因为我们可以报全局看做是一个函数,那么全局就形成了闭包了。但是这也没啥意义,所以你可以这么理解,但是不要用到实际开发中,哈哈

最后,总结一下(别人都总结,我也总结)
闭包无处不在,我们很多时候都在使用闭包,因为他能让我们写出更好、更优雅、更易维护的代码

全部评论

相关推荐

10-18 13:01
已编辑
西安理工大学 C++
小米内推大使:建议技能还是放上面吧,hr和技术面试官第一眼想看的应该是技能点和他们岗位是否匹配
点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务