什么是闭包?闭包的用途是什么?闭包的缺点是什么?

167 阅读2分钟

:什么是闭包?

:闭包就是能够读取其他函数内部变量的函数。

:闭包的用途是什么?

:闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。闭包的另一个用处,是封装对象的私有属性和私有方法。

:闭包的缺点是什么?

:外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。

什么是闭包解释

JavaScript 有两种作用域:全局作用域和函数作用域。

函数内部可以直接读取全局变量。

函数外部无法读取函数内部声明的变量。

在一般情况下,函数外部无法读取函数内部声明的变量,下面代码中,函数f1内部声明的变量n,函数外是无法读取的。

function f1() {

var n = 999;

}

console.log(n)

但是我们可在函数内多添加一个函数,并返回这个函数,就可读取函数内部的变量了。


function f1() {

var n = 999;

function f2() {

console.log(n);

}

return f2;

}

var result = f1();

result(); // 999

上面代码中,在函数f1内部又增加了一个函数f2,将函数f2设置为函数f1的返回值,由于f2可以读取f1的内部变量,所以通过返回f2就可以在外部获得f1的内部变量了,这就是典型的闭包。

闭包的用途解释

  1. 读取函数内部的变量已在上文解释完毕

  2. 让变量始终保持在内存中


function createIncrementor(start) {

return function () {

return start++;

};

}

var inc = createIncrementor(5);

inc() // 5

inc() // 6

inc() // 7

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

  1. 封装对象的私有属性和私有方法

function Person(name) {

var _age;

function setAge(n) {

_age = n;

}

function getAge() {

return _age;

}

return {

name: name,

getAge: getAge,

setAge: setAge

};

}

var p1 = Person('张三');

p1.setAge(25);

p1.getAge() // 25

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