你眼中的星河烂漫 是我不曾见过的世外桃源
闭包就是能够读取其他含少数内部的变量的函数, 在js中, 只有函数内部的子函数才能读取局部变量, 所以闭包可以理解成 “定义在一个函数内部的函数”。在本质上,闭包是将函数内部和函数外部链接起来的桥梁。
举例
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName; // 将函数return 出去
}
var myFunc = makeFunc(); // 调用函数 获得到的是一个函数体
myFunc(); // 调用 return 出来的函数
闭包是由函数以及创建该函数的词法环境组合而成。这个环境包含了这个闭包创建时所能访问的所有局部变量。在我们的例子中,myFunc
是执行makeFunc
时创建的 displayName
函数实例的引用,而 displayName
实例仍可访问其词法作用域中的变量,即可以访问到name
。由此,当myFunc
被调用时,name
仍可被访问,其值 Mozilla
就被传递到alert
中。
实用的闭包
闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。
因此,通常你使用只有一个方法的对象的地方,都可以使用闭包。
在 Web 中,你想要这样做的情况特别常见。大部分我们所写的 JavaScript 代码都是基于事件的 — 定义某种行为,然后将其添加到用户触发的事件之上(比如点击或者按键)。我们的代码通常作为回调:为响应事件而执行的函数。
假如,我们想在页面上添加一些可以调整字号的按钮。一种方法是以像素为单位指定 body 元素的 font-size,然后通过相对的 em 单位设置页面中其它元素(例如header)的字号:
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
}
h1 {
font-size: 1.5em;
}
h2 {
font-size: 1.2em;
}
我们的文本尺寸调整按钮可以修改 body 元素的 font-size 属性,由于我们使用相对单位,页面中的其它元素也会相应地调整。
以下是 JavaScript:
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
//size12,size14 和 size16 三个函数将分别把 body 文本调整为 12,14,16 像素。
//我们可以将它们分别添加到按钮的点击事件上。如下所示:
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>