闭包一言蔽之为:一个持有外部环境变量的函数就是闭包(能够读取其他函数内部变量的函数)。
有一个比喻为:通俗地讲就是别人家有某个东西,你想拿到但是因为权限不够(不打死你才怪),但是你可以跟家里的孩子套近乎,通过他拿到!
这个家就是局部作用域,外部无法访问内部变量,孩子是返回对象,对家里的东西有访问权限,借助返回对象间接访问内部变量!
一:举几个个栗子:
let a = 1
let b = function(){
console.log(a)
}//这是通过a这个自由变量来访问的
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);//add5 和 add10 都是闭包。它们共享相同的函数定义,但是保存了不同的词法环境。在 add5 的环境中,x 为 5。而在 add10 中,x 则为 10。
console.log(add5(2)); // 7
console.log(add10(2)); // 12
总结:一定的词法环境决定闭包,并且闭包能够产生新的此法环境
二:闭包的实用性:
//首先定义一个函数
function makeSizer(size){
//返回一个结果
return function(){
document.body.style.fontSize=size+'px'
}
}
var size12=makeSizer(12)/
document.getElementByID('size-12').onclick=size12//绑定ID
<a href="#" id="size-12">12</a>
三:闭包使用的错误提醒:
循环中常见的闭包问题:
<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email"></p>
<p>Name: <input type="text" id="name" name="name"></p>
<p>Age: <input type="text" id="age" name="age"></p>
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);//由于i的变量提升,最后得到的是循环系结束的结果。item=helpText[3]
}
}
}
setupHelp();
更正的方法有1:用 let 代替var
2:创建一个return函数或者利用IIFE (Immediately Invoked Function Expression)
正确的方法见连接
!https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
网友评论