js闭包函数

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

函数f2就在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行。父对象的所有变量,对子对象都是可见的,反之则不成立。but只要把f2作为返回值,我们就可以在f1外部读取它的内部变量了。

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

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

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

作用:①可以读取外层函数内部的变量。②让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在

下面的例子,闭包使得内部变量记住上一次调用时的运算结果。

function createAdd(num) {
  return function () {
    return num++;
  };
}

var innerFun= createAdd(5);

innerFun() // 5
innerFun() // 6
innerFun() // 7

上面代码中,num是函数createAdd的内部变量。通过闭包,num的状态被保留了,每一次调用都是在上一次调用的基础上进行计算。从中可以看到,闭包inc使得函数createAdd的内部环境一直存在。所以,闭包可以看作是函数内部作用域的一个接口。

为什么闭包能够返回外层函数的内部变量?原因是闭包(上例的innerFun)用到了外层变量(num),导致外层函数(createAdd)不能从内存释放。只要闭包没有被垃圾回收机制清除,外层函数提供的运行环境也不会被清除,它的内部变量就始终保存着当前值,供闭包读取。

function Person(name) {
  var age;
  function setAge(n) {
    age = n;
  }
  function getAge() {
    return age;
  }

  return {
    name,
    getAge,
    setAge,
  };
}

var p1 = Person('潇洒');
p1.setAge(18);
p1.getAge() //18

上面代码中,函数Person的内部变量age,通过闭包getAgesetAge,变成了返回对象p1的私有变量。

阮一峰的js很不错,推荐大家看。

上一篇:ExtJS入门教程04,这是一个超级好用的grid


下一篇:Codeforces Round #579 (Div. 3) F1. Complete the Projects (easy version) 排序 + 贪心