闭包经典题(答案及解释)

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值得函数,避免混淆
上一篇下一篇

猜你喜欢

热点阅读