闭包
是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落。这些外部执行域的非持久型变量神奇地保留它们在闭包最初定义(或创建)时的值(深连结)。简单来说,闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对),而这些键值对是不会随上一级函数的执行完成而销毁。
闭包可以用在许多地方。它的最大用处有两个
- 可以读取函数内部的变量
- 让这些变量的值始终保持在内存中
让我们看一下下面的例子:
function fun() {
var a = 2;
//为了访问fun()中的a
return function () {
return a;
}
}
document.write(fun()());
//匿名函数function () { return a; }就是一个闭包
让我们再看一个例子:
function sum(arg) {
var fun = function () {
return arg;
}
arg++;
return fun;
}
//返回的是最新的值
document.write(sum(5)());
读取/设置访问器
闭包的用途应用之一:可以读取函数内部的变量
var getValue, setValue;
(
function () {
var value = 0;
getValue = function(){
return value;
}
setValue = function(v){
value = v;
}
}
)()
document.write(getValue() + "<br/>");
setValue("John")
document.write(getValue() + "<br/>");
迭代器
闭包的用途应用之一:让这些变量的值始终保持在内存中
function next(arr) {
var i = 0;
return function () {
return arr[i++];
}
}
var temp = next([1, 2, 3]);
document.write(temp());
document.write(temp());
document.write(temp());
循环中的闭包
让我们看一下下面的例子:
function sum() {
var arr = [];
for (var i = 0; i < 3; i++) {
arr[i] = function () { return i; }
}
return arr;
}
var temp = sum();
for (var i = 0; i < 3; i++) {
//arr的里面的值是 function () { return i; }所以要加()执行一下
document.write(temp[i]());
}
解决方式一:利用中间函数是i 在每次迭代的时候“本地化”其值。
function sum() {
var arr = [];
for (var i = 0; i < 3; i++) { arr[i] = aa(i); }
return arr;
}
function aa(i) {
return i;
}
var temp = sum();
for (var i = 0; i < 3; i++) {
//arr的里面的值是 0,1,2,所以不需要加()执行一下
document.write(temp[i]);
}
解决方式二:利用自调用函数(关于‘自调用函数不明白的朋友,请另一篇文章’JavaScript中的自调用函数‘)
function sum() {
var arr = [];
for (var i = 0; i < 3; i++) {
arr[i] = (function (x) { return x; })(i)
}
return arr;
}
var temp = sum();
for (var i = 0; i < 3; i++) {
//arr的里面的值是 0,1,2,所以不需要加()执行一下
document.write(temp[i]);
}