在相关的书籍《javascript高级程序设计》中对闭包的描述是这样的:
闭包,其实是一种语言特性,它是指的是程序设计语言中,允许将函数看作对象,然后能像在对象中的操作般在函数中定义实例(局部)变量,而这些变量能在函数中保存到函数的实例对象销毁为止,其它代码块能通过某种方式获取这些实例(局部)变量的值并进行应用扩展。
简单的写一个代码例子即可了解相关内容:
function test(){ var inner = '我是test函数内部的变量'; return function pg(){ console.log(inner); } } var pg = test(); pg()//我是test函数内部的变量
通过上述的代码可以看出,在返回的pg函数中获取了上一级作用域中的变量inner,从作用域角度来看则是返回的pg函数在自身的函数当中并未找到相关的inner变量,因此会跨越到父级作用域获取test函数中的inner变量,最终进行输出
这样形成的闭包则是可以保证inner成为一个私有变量,在全局作用域下是无法直接访问test函数中的inner变量的,只能通过闭包的方式间接获取得到,因此能够保证一定的安全性(此处先不讲执行栈的相关知识)
但是这样子也会显示出闭包相关的缺点
首先我们可以看到,在全局作用域下我们是有一个test函数的,test作用域里面有inner 和pg,pg作用域里面执行控制台输出inner 的变量
由于pg函数里面需要访问到test作用域下的inner 变量,而他们不处在同一个作用域中,所以两者相互牵引,需要输出inner ,test中的变量inner 就必须得在,作用域链查找到test的时候找到inner 了,输出inner 的时候,垃圾回收机制会认为pg还没有执行完成,因为此时的作用域链查找已经到了test作用域下,所以不会清理inner 的内存空间
因此如果我们多次使用闭包,则会给程序带来内存占用过多,导致相关的性能问题
因此闭包总结如下:
优点:
1.可以读取函数内部的变量
2.可以避免全局污染
缺点:
1.闭包可能会导致变量不会被垃圾回收机制所清除,因而消耗大量内存
2.不恰当地使用闭包可能会造成内存泄漏的问题
function debounce(event, time) { let timer = null; return function (...args) { clearTimeout(timer); timer = setTimeout(() => { event.apply(this, args); }, time); }; }
function throttle(event, time) { let timer = null; return function (...args) { if (!timer) { timer = setTimeout(() => { timer = null; event.apply(this, args); }, time); } } }
在这里就不多说防抖以及节流函数的用处以及原理了,主要讲的是闭包本身的一些概念以及用途