闭包
- 闭包的定义: 当一个内部函数被其外部函数之外的变量引用时,就形成了一个闭包。
// 以下面的代码为例:即是外部的变量c引用了a内部的b函数,这样形成了一个简单的闭包
function A(){
function B(){
console.log('Hello Closure!');
}
return B;
}
var C = A();
C();// Hello Closure!
闭包的用途
- 先看看js的GC制度:在 Javascript 中,如果一个对象不再被引用,那么这个对象就会被 GC 回收,否则这个对象一直会保存在内存中。
- 看一个利用闭包的优雅小例子,使用某个变量使其一直保存在内存中且不污染全局变量:
// count 是函数A 中的一个变量,它的值在函数B 中被改变,函数 B 每执行一次,count 的值就在原来的基础上累加 1 。因此,函数A中的 count 变量会一直保存在内存中
function A() {
var count = 0;
function B() {
count ++;
console.log(count);
}
return B; // 不要忘记!!!
}
var C = A();
C();// 1
C();// 2
C();// 3
// 这种方法下巧妙的完成了一个累加器
闭包高级写法
- 在实际应用中,闭包一般与匿名函数一起使用
// 既然上边一段代码可以看出a函数仅仅是为了让count变量在内存中一直存在而已,因此我们可以将这个函数变成匿名函数并直接执行
(function (document) {
var viewport;
var obj = {
init: function(id) {
viewport = document.querySelector('#' + id);
},
addChild: function(child) {
viewport.appendChild(child);
},
removeChild: function(child) {
viewport.removeChild(child);
}
}
window.jView = obj;
})(document);
- 这里边用到了匿名函数:
(function(3){})(4)
- 与普通函数区别除了没有名字外是它有最大的外括号,相当于定义了这个函数,最后的括号相当于是执行这个匿名函数,括号3,4分别对应普通函数的形参和实参,根据需要传入即可。
上边一段代码可变成:
var f = function(document) {
var viewport;
var obj = {
init: function(id) {
viewport = document.querySelector('#' + id);
},
addChild: function(child) {
viewport.appendChild(child);
},
removeChild: function(child) {
viewport.removeChild(child);
}
}
window.jView = obj;
};
f(document);
注意不能过度使用闭包,,因为它对内存的花销较大