目录
一、什么是闭包
闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。
二、什么是作用域
作用域主要分为两种:全局变量和局部变量。
局部变量
定义在函数内部,只能在函数中使用的变量,作用范围是从函数开始到结尾,即在**{}**里。
这里定义的a
就是局部变量。
function myTest1(){
var a = 3;
return a;
}
console.log(a);//a is not defined
console.log( myTest1());//3
全局变量
常常定义在函数外部,拥有全局作用域,即在 JavaScript 代码的任何地方都可以访问
这里定义的
b
就是局部变量。
var b = 3;//全局变量
function myTest2(){
return b;
}
console.log(b);//3
console.log(myTest2());//3
从这里我们就可以知道,函数内部可以调用全局变量,但是函数外部无法读取函数内的局部变量
函数内部声明变量的时候,必须使用var命令去声明一个变量。如果不用的话,就会声明了一个全局变量。
function myTest3(){
var c = 4;
d=3;
return c,d;
}
console.log( myTest3());//4,3
console.log(d);//3
console.log(c);//c is not defined
在这里我们
c
和d
都是在函数内部声明的,但是因为c
使用了var
,而d
没有使用var
声明,所以在外部能够使用d
;也就是所谓的声明了一个全局变量
三、闭包的形成
function fun1() {
var name = "zs"; // name 是一个被 init 创建的局部变量
function fun2() { // displayName() 是内部函数,一个闭包
alert(name); // 使用了父函数中声明的变量
}
fun2();
}
fun1();
fun1()
创建了一个局部变量name
和一个名为fun2()
的函数。fun2()
是定义在fun1()
里的内部函数,并且仅在fun1()
函数体内可用。请注意,fun2()
没有自己的局部变量。然而,因为它可以访问到外部函数的变量,所以fun2()
可以使用父函数fun1()
中声明的变量name
。
四、闭包的优缺点
优点:
- 保护函数内的变量安全,加强了封装性
- 在内存中维持一个变量(用的太多就变成了缺点,占内存)
缺点:
- 闭包有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅因为它常驻内存,更重要的是,对闭包的使用不当会造成无效内存的产生,导致内存泄漏。