我对于闭包的简单理解
什么是闭包
简单来说:闭包就是能够用于获取其他函数内部变量的函数
什么是作用域
要理解闭包就要先理解作用域。
JavaScript 的作用域就两种:全局作用域 和 局部作用域。其实还有第三种 eval(),但是不建议使用,所以在这里不讨论。
全局作用域: 在函数外部定义的变量就是 全局变量。
局部作用域: 在函数内部定义的变量就是 局部变量。
在函数内部可以读取函数外部或者全局的变量,但是在函数外部无法读取函数内部的局部变量。
这句话怎么理解?可以看个例子。
例子 1:
var sName = 'Rogers'; // 这是全局变量
function fn1(){
console.log(sName); // 函数内部可以读取全局变量
}
fn1(); // 终端中输出 ‘Rogers'
说明在 fn1() 函数内部可以读取全局变量
来看一个例子。
例子 2:
function fn2(){
var sName = 'Lewis'; // 函数内部的局部变量
}
console.log(sName); // 错误:Uncaught ReferenceError: sName is not defined
说明在函数的外部无法读取函数内部的变量
再来看一个例子
例子 3:
function fn1(){
var sName = 'Jimmy';
function fn2(){
console.log(sName); // Jimmy
}
fn2();
}
fn1();
那么,如果我们就是想在函数的外部获取函数内部的局部变量呢?怎么办?用正常的方法是办不到的,可以用变通的方法办到。那就是在函数的内部再定义一个函数。就像上面的例子3一样。函数 fn1 是外部函数,函数 fn2 是内部函数。就像上面写的一样,内部函数可以获取外部函数的变量,所以 fn2 这个内部函数就可以获取外部函数 fn1 的变量。然后再把它作为返回值返回就可以了。于是我们就可以再外部使用内部函数的变量了。
来看个和例子3差不多的例子:
例子 4:
function fn1(){
var sName = 'Johnson';
function fn2(){
return sName;
}
return fn2;
}
在外部函数 fn1 的内部有变量 sName 和内部函数 fn2 。对于 fn2 来说, sName 就是它的外部变量,所以它可以获取 sName,然后再返回它。
var f = fn1();
console.log(f()); // 'Johnson'
所以我们就可以在外部获取函数内部的变量了。
什么用?
闭包有什么用?这是我们要搞清楚的。闭包主要有两个用处:
1,我们上面说了,就是获取函数内部的变量。
2,另一个作用,就是让变量始终保存在内存
第二点该怎么理解?我们知道变量如果不再使用了,那么垃圾回收器就会收回它,用于释放内存。比如说一个函数执行完毕之后,函数内部的变量就不再需要了,那垃圾回收器(GC)就会收回变量,释放内存。但是由于有闭包的存在,内部函数还在使用外部函数的变量,这就导致了外部函数的变量无法被回收。那么外部函数也会继续存在在内存中。所以它就会始终保持在内存中。
注意点: 由于闭包的存在,要注意内存泄漏问题。
写作日期:2018.11.10