每次面试笔试都会遇到的题,js的闭包,接下来梳理一下吧
var str = '变量'; //str是变量
function fn () { //fn是函数
console.log(str) //在函数fn中可以访问变量str
}
这就是一个闭包,简单的说:闭包就是由 一个变量 和 一个内部可以访问到变量的函数 组成
但是我们常常看到的都是被一个函数包住,比如
function getStr () {
var str = '变量'
function fn () {
return str;
}
return fn
}
// 调用
getStr();
没错,这就是一个闭包,这是个由 (变量str) 和 内部能访问到str的函数fn 组成的。
为什么要函数套函数呢?
是因为需要局部变量,所以才把 str 放在一个函数里,如果不把 str 放在一个函数里,str 就是一个全局变量了,达不到使用闭包的目的——隐藏变量。
有些人看到「闭包」这个名字,就一定觉得要用什么包起来才行。其实这是翻译问题,闭包的原文是 Closure,跟「包」没有任何关系。
所以函数套函数只是为了造出一个局部变量,跟闭包无关。
为什么要 return fn呢?
因为如果不 return,你就无法使用这个闭包。把 return fn 改成 window.fn = fn 也是一样的,只要让外面可以访问到这个 fn 函数就行了。
所以 return fn 只是为了 fn 能被使用,也跟闭包无关。
需要注意的是:闭包只能取得包含函数中的任何变量中return的最后一个值
闭包的作用
闭包常常用来「间接访问一个变量」。换句话说,「隐藏一个变量」。
函数执行形成的私有作用域,保护里面的变量不受外界干扰的机制。
闭包会造成内存泄露吗?
不会!内存泄露是指你用不到(访问不到)的变量,依然占居着内存空间,不能被再次利用起来。
闭包里面的变量明明就是我们需要的变量(lives),凭什么说是内存泄露?
这个谣言是如何来的?
因为 IE。IE 有 bug,IE 在我们使用完闭包之后,依然回收不了闭包里面引用的变量。
这是 IE 的问题,不是闭包的问题。