闭包
闭包是纯函数式编程语言的一个特征。
1. 闭包是如何工作的
闭包:它是一个函数在创建时允许自身函数访问并操作该自身函数之外的变量时所创建的作用域。闭包可以让函数访问所有的变量和函数,只要该变量和函数存在于该函数声明时的作用域内就行。
var outerValue = 'outer';
var later;
function outerFunction () {
var innerValue = 'inner';
function innerFunction () {
console.log(outerValue); // outer
console.log(innerValue); // inner
}
later = innerFunction;
}
outerFunction();
later();
在声明innerFunction时候,不仅声明了函数,还创建了一个闭包,该闭包不仅包含函数声明,还包含了该作用域中的所有变量。当innerFunction()执行的时候,当时声明的作用域已经消失了,通过闭包,改函数还是能够访问到原始作用域的。
2. 使用闭包
2.1 私有变量
私有变量是闭包的一种常见用法,来限制变量的作用域。
function Fight () {
var feints = 0;
this.getFeints = function () {
return feints;
};
this.feint = function () {
feints ++;
};
}
var fight = new Fight();
fight.feint();
console.log(fight.getFeints()); // 1
console.log(fight.feints); // undefined
JavaScript作用域规则显示了它的可访问性只能在构造器内部。要让外部代码访问到改内部变量,定义了一个存储的方法getFeints,该方法只能对内部变量的读取,但是不能写入。在feint方法中,控制(增加)变量的值。
构造函数Fight内部的私有变量feints,该变量只可以通过闭包存在于内部方法,不存在于构造器外部。这就构成了一个闭包。
2.2 回调和计时器
在处理回调或使用计时器时会用到闭包,这两种情况,函数都是在后期未指定的时间进行异步调用,在这种函数内部,经常需要访问外部数据。例如:jQuery中ajax中的回调函数。
计时器
function animate (element) {
var ele = document.getElementById(element);
var tick = 0;
var timer = setInterval(function () {
if (tick < 100) {
ele.style.left = tick + 'px';
tick++;
} else {
clearInterval(timer);
}
}, 100);
}
animate('roll');
计时器的匿名函数中,使用了ele
,tick
,timer
这三个变量。创建animate方法就默认创建了一个闭包