一、为什么会产生闭包?
在开始说闭包之前,我们要先理解一下变量的作用域,变量的作用域无非有两种:全局作用域和局部作用域。
出于种种原因,有时候我们需要得到函数内部的局部变量。
但是,在正常情况下这个是办不到的,只有通过变通的方法才能实现。
这个方法就是,在函数的内部再定义一个函数。
function f1() {
let a = 1
function f2() {
console.log(a);
}
}
在上面的代码中,函数 f2 就被定义在了 函数 f1 中,这时 f1 内的所有局部变量对 f2 都是可见的。
但是反过来就不行,f2 内部的局部变量对 f1 就是不可见的。
那么既然 f2 可以读取 f1 中的变量,那么只要把 f2 作为返回值,我们不就可以在 f1 外部读取它内部的变量了吗!
function f1() {
let a = 1
function f2() {
console.log(a);
}
return f2;
}
var result = f1();
result()
二、闭包是什么?
定义:如果一个函数用到了外部的变量,那么这个函数加这个变量,就叫做闭包。
比如,这里就是一个闭包:
function f1() {
let a = 1
function f2() {
console.log(a);
}
}
// 函数 f2 可以访问外部的变量 a,那么函数 f2 和 外部的变量 a 就构成了闭包
三、闭包的作用是什么
闭包常常用来间接访问一个变量,换句话说,就是隐藏一个变量。
假如我们在开发一个商城项目,里面有产品数量的代码。如果不使用闭包,那么你可以直接使用一个全局变量:
window.number = 200
这样子写存在一个问题,万一不小心把这个值改成了 0 该怎么办,所以我们不能让人直接访问这个变量。
使用局部变量?使用局部变量别人又无法进行访问。
可以暴露一个访问器(函数),让别人可以“间接访问“。
代码可以这样子写:
!function () {
var number = 200
window.addGoods = function () {
number += 1
}
window.deleteGoods = function () {
number -= 1
}
}()
window.addGoods()
这个时候,你就可以调用 window.addGoods 来添加商品,调用 deleteGoods 来下架商品。
这其中一共有两个闭包:
- number 和 addGoods 组成了一个闭包
- number 和 deleteGoods 组成了一个闭包
四、闭包的缺点是什么?
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页性能问题。
解决方法是,在退出函数之前,将不适用的局部变量全部删除。
五、使用闭包的注意点
闭包会在父函数外部改变父函数内部的值。
所以,如果你把父函数当做对象使用,把闭包当做他的公用方法,把内部变量当做它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。