闭包经典题(答案及解释)
2018-09-21 本文已影响0人
锋享前端
// 答案选D
// 这是一个闭包。
把for(var i = 0; i < 4; i++) {
elems[i].onclick = function () {
alert(i);
};
}
// 拆成这样来看就明白
for (var i = 0; i < 4; i++) {
function () {
alert(i); //这里输出的是4,因为被循环了
};
}
// 和这个差不多
var i = 0;
function () {
alert(i); //这里输入的是0;
}
// alert的i, 其实还是for里面的那个i, 因为i循环了4次, 所以alert的i累加了4次, 就成了4。
// 闭包: 有权访问另一个函数作用域中的变量函数。 闭包保存的是整个 变量对象, 而不是某个特殊的变量。
// 闭包与变量: 闭包只能取得包含函数中任何变量的最后一个值。
//
// 每个li标签的onclick事件执行时, 本身onclick绑定的function的作用域中没有变量i, i为undefined, 则解析引擎会寻找父级作用域, 发现父级作用域中有i, 且for循环绑定事件结束后, i已经赋值为4, 所以每个li标签的onclick事件执行时, alert的都是父作用域中的i, 也就是4。 这是作用域的问题。
var elements = document.getElementsByTagName('li');
var length = elements.length;
for (var i = 0; i < length; i++) {
elements[i].onclick = (function (a) {
return function () {
alert(a);
}
})(i);
}
//用此代码可以依次弹出 0,1,2,3(闭包可以“包养”外部函数变量)
// 或者
var elements = document.getElementsByTagName('li');
var length = elements.length;
var handler = function (i) {
return fucntion() {
alert(i);
}
}
for (var i = 0; i < length; i++) {
elements[i].onclick = handler(i);
}
// 避免在循环中创建函数,可以在循环之外创建一个辅助函数,让这个辅助函数返回一个绑定了当前i值得函数,避免混淆