闭包
首先来个例子
// 代码1
function fn1() {
var n = 19;
function fn2 () {
console.log(n);
}
return fn2;
}
var result = fn1();
result(); //19
上面代码1中,函数fn1的返回值就是函数fn2, fn2可以读取fn1的内部变量,闭包就是函数fn2,即能够读取其他函数内部变量的函数。可以把闭包简单理解成“定义在一个函数内部的函数”。
闭包可以读取函数内部的变量,让这些变量始终保持在内存中,闭包可以记住上一次调用的运行结果。
// 代码2
function createIncrementor(n) {
return function () {
return n++;
};
}
var inc = createIncrementor(5);
inc() // 5
inc() // 6
inc() // 7
上面代码2中,start是函数createIncrementor的内部变量。通过闭包,start的状态被保留了,每一次调用都是在上一次调用的基础上进行计算。从中可以看到,闭包inc使得函数createIncrementor的内部环境,一直存在。所以,闭包可以看作是函数内部作用域的一个接口。
// 代码3
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
闭包的另一个用处,是封装对象的私有属性和私有方法。
上面代码3中,函数Person的内部变量_age,通过闭包getAge和setAge,变成了返回对象p1的私有变量。
- 注意,外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。
参考教程JavaScript 标准参考教程(alpha)