引言
因为想把自己的想法实现光会后端还是不够的,所以开始学习JS.
闭包
闭包让开发者可以从内部函数访问外部函数的作用域.闭包会随着函数的创建而被同时创建. 允许将函数与其所操作的某些数据(环境)关联起来.
案例
实用的闭包
通常使用只有一个方法的对象的地方,都可以使用闭包.
function makeSizer(size) {
return function () {
document.body.size.fontSize = size + "px";
}
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
document.getElementById("size-12").onclick = size12;
document.getElementById("size-14").onclick = size14;
document.getElementById("size-16").onclick = size16;
使用闭包模拟私有方法
js没有原生支持方法私有化(话说Class不是支持了私有方法嘛?)
var Counter = (
function () {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function () {
changeBy(1);
},
decrement: function () {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
}
)();
创建了一个立即执行的匿名函数体,包含了两个私有变量和方法,同时创建多个实例,闭包之间互不影响.
让这些变量的值始终保持在内存中
function f1() {
var n = 999;
nAdd = function () {
n += 1
}
function f2() {
alert(n);
}
return f2;
}
var result = f1();
result(); // 999
nAdd();
result(); // 1000
由于f2被赋值给了result,导致f1和内容变量n一直存在于内存中. nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量.其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包, 所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作.
思考题
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
return function () {
return this.name;
};
}
};
alert(object.getNameFunc()()); // The Window
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
var that = this;
return function () {
return that.name;
};
}
};
alert(object.getNameFunc()()); // My Object
重点在于this指针的指向问题,return function()其实是一个匿名的全局函数,则this是指向Window对象.
性能考量
如果不是某些特定任务需要使用闭包,在其他函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响.