关于闭包的知识回顾与面试题精解

344 阅读3分钟

今天突然发现自己忘记闭包知识点了,复习一下!!!

注:这篇博文只是回顾知识,若看详解闭包请翻看以往博文
先回顾一下闭包基础知识
何为闭包?

简单点说在A函数里面创建一个函数B,则B就是闭包

闭包的作用:
1. js作用域,函数内部可以调用函数外部的变量,反之不行,如果需要,则可以使用闭包

var n = 999;
function f1() {
    console.log(n);
}
f1()//999   

上面例子中,函数f1()可以读取全局变量n。但是函数外部却无法读取到函数内部声明的变量。

var n = 999;
function f1() {
    console.log(n);
    var n1 = 888
}
console.log(n1)
f1()//999   

运行结果如下: 函数外访问函数内变量直接显示n1未定义,报错。
那么我们有时候需要得到函数内部的变量,也就只能通过在函数内部在定义一个函数。

function f1() {
  var n = 999;
  function f2() {
  console.log(n); // 999
  }
}

上面代码中,函数f2就在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。

我们通过上面例子看出来了,f2可以读取f1的局部变量,那么只要把f2作为返回值,我们就可以在f1外部读取它的内部变量了。

function f1() {
  var n = 999;
  function f2() {
    console.log(n);
  }
  return f2;
}

var result = f1();
result(); // 999

上面代码中,函数f1的返回值就是函数f2,由于f2可以读取f1的内部变量,所以就可以在外部获得f1的内部变量了。

闭包也就是函数f2,即能够读取其他函数内部变量的函数。由于在 JavaScript语言中,只有函数内部的子函数才能读取内部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。闭包最大的特点,就是它可以“记住”诞生的环境,比如f2记住了它诞生的环境f1,所以从f2可以得到f1的内部变量。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

2. 一般函数执行完后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象),但是闭包情况下,不会被摧毁,所以闭包,会占用更多的占用内存。
从实例中感受一下

var name = "The Window";   
    var object = {   
    name : "My Object",   
    a : function(){   
        return function(){
        return this.name;
            
        };   
}   
};   
alert(object.a()()); 

如上输出

如上解析:

object.a()();
是一个立即执行函数,相当于:
object.a()() ==> function(){   
                    return function(){
                    return this.name;
                    };   
                    }()

结果返回return this.name;
this指向window也就是var定义的全局变量
var name = "The Window";
输出结果也就是The Window

下面给出一个例子看看闭包规范:

function outerFun(){
  var a=0;
  function innerFun(){
    a++;
    alert(a);
  }    
 }
innerFun()

上面的代码是错误的.innerFun()的作用域在outerFun()内部,所在outerFun()外部调用它是错误的

改成如下,也就是闭包:

function outerFun()
{
 var a=0;
 function innerFun()
 {
  a++;
  alert(a);
 }
 return innerFun;  //注意这里
}

这样当它执行的时候又返回函数innerFun(){}就形成了一个闭包。

总:当内部函数 在定义它的作用域 的外部 被引用时,就创建了该内部函数的闭包 ,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被 释放,因为闭包需要它们.