好像闭包也是JS绕不过的一个问题。
闭包的定义
第一个是闭包的形式。简而言之就是一个函数返回被外部调用的函数,makeFunc是一个闭包,它返回了displayName的定义,而这个displayName能够记录makeFunc运行的时候的局部变量。
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
闭包的用途
产生不同的回调函数
function makeSizer(size) {
return function() {
document.body.style.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;
闭包模拟私有方法
私有方法不仅仅有利于限制对代码的访问:还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */
首先Count = (function(){})(),立即执行函数,得到return的一个对象,对象保存了不同的函数,而函数能够访问闭包中的元素。同时,闭包中的私有变量并不能被外界访问。
闭包的循环陷阱
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}
}
setupHelp();
这个是典型的循环问题,因为共享一个变量,所以每次真正调用的是。
闭包的缺点
除了循环陷阱,性能和内存也是有问题的。
网友评论