又要来更新闭包了。闭包的底层不简单,需要了解上下文,执行上下文,词法作用域等。
闭包
闭包是一个受到保护的变量空间,由内嵌函数生成。
JavaScript具有函数级的作用域(let是块级作用域),这意味着在函数内部的变量在函数外部不能被访问。 然而,其作用域又是词法性质的,意味着函数运行在定义它的作用域中,而不是调用它的作用域中。
说白了,他就是把作用域保存下来了。不然你怎么可能访问到本应该销毁的东西。
注意:
- 因为是作用域,并不是函数才有,像典型的for循环使用let去setTimeout,内部原理也是一个个的闭包。
当通过返回一个含有私有变量引用的方式来将函数传递到词法作用域外部时,就已经创建了条件了,下一步调用就会生成闭包了。
闭包生成条件还有保存对创建的该实例,需要注意的一点就是,如果重复创建实例,形成闭包,不如将其弄成单例模式保存起来,即模块暴露,return一个对象出来,才是好的实践。
学好一定要解决这几个疑问,而在此我不解释全部:
- 怎么才能形成闭包呢?
- 怎么看还用不用,也就是我说的确保不用了呢?
- 那怎么去主动释放他的内存空间呢?
- 那又为什么要使用闭包呢?
任何一个函数他都有可能形成闭包,关键在于她有没有被用到,比方说b函数被a用到了,而a又被c用到了,你看,b它是被使用的,肯定不能放过他,得让他留在内存里,以防止重新计算浪费时间呀。
理解了形成之后,相信你一定知道了形象的理解他的概念,只要还要用,那我就保存了,所以一定会有不用的时候,检测没有再使用到这个函数的东西了,那就垃圾回收机制给回收了,感兴趣的可以去看看详情。
每一个通过闭包访问变量的函数都有一个作用域,其包含闭包的全部信息。使用闭包时,所有的信息都会存储在内存中,直到js引擎确保信息不再使用,或者页面卸载,才会清理。
那如果我不想走自动回收这条道,我想自己清理,有什么方法呢?肯定想到了null这个空指针对象了,将其赋值为null就可以了。下一次垃圾回收就会把他回收喽。还有没有呢,还有一个delete,可以删除obj.name这样的类型。(关于垃圾回收还有WeakMap等虚持有结构。)