什么是闭包?
闭包是指能够访问另一个函数作用域的变量的函数。通俗来说,闭包就是一个函数,这个函数能够访问其它作用域中的变量。
我们先来看一个例子:
function outer(m){
return {
inner:function(){
console.log(m)
}
}
}
outer('测试').inner()
执行上述代码后,有的同学就懵了,m不是outer这个函数作用域的吗?怎么能在inner函数里访问到,这就是闭包的魅力之处。
为什么闭包函数能够访问其他函数的作用域 ?
一说到为什么闭包函数能够访问到其它函数的作用域,这就涉及到一个作用域链的知识点了,作用域链的知识点我就不在这里详细去解释了,大体就是在函数作用域内的变量值,当在该函数作用域体内没有找到的话,就会向上层作用域进行查找,若依然没有,就一直查找到全局作用域中,这样就形成了一个作用域链。
所以上面例子中,inner中访问变量m,但在该函数体内没有找到定义,于是就向让一层outer函数体内查找。也就是说outer函数的作用域在inner函数的作用域链中。
闭包中的this对象
在闭包中使用this对象会让代码复杂化,this对象会在运行时绑定到执行函数的上下文(箭头函数除外)。如果在全局函数中调用,非严格模式下this指向window,严格模式下是undefined。如果是作为某个对象的方法调用,则this指向该对象。
window.message = 'hello word!';
let obj = {
message: "nice to meet you !",
getMessage(){
let that = this; // 将this保存到闭包能够访问到的that中
return function(){
return that.message;
}
}
}
上面这个例子,无论如何去调用obj对象中的getMessage方法,返回的值都是obj里的message。
内存泄漏
在使用闭包的时候,由于某些浏览器的内存回收机制问题,可能会导致内存泄漏的问题,因此在使用闭包后,我们最好将其中保存在闭包的里变量设置一下,从而确保其内存可以在适当的时候被回收。