如何控制变量吊装

How To Control Variable Hoisting?

本文关键字:控制变量      更新时间:2023-09-26

我有一个问题,从一个数组绑定函数到一些元素,但我得到这个错误后,我点击任何元素类"class"。

Uncaught TypeError: object function (){alert(1)},function (){alert(2)},function (){alert(3)},function (){alert(4)}的属性'4'不是一个函数

var c = [
    function(){alert(1)},
    function(){alert(2)},
    function(){alert(3)},
    function(){alert(4)}
];
function test(b){
    for(var i = 0; i < b.length; i++){
        $('.class').eq(i).bind('click', function(){
            b[i]();
        });
    }
}
test(c);

我认为变量I保持它的上一个值

任何解决方案或解释将非常感激。

你需要一个闭包——在js中变量的作用域是由函数决定的。使用jQuery,只需使用.each:

$('.class').each(function(i) {
     $(this).on('click', function(){
         alert(i+1);
     });
});

但是,如果你真的需要一个不同函数的数组,你可以直接将函数本身绑定为处理程序:

var elems = $('.class');
for (var i=0;i<b.length;i++) {
    elems.eq(i).on('click', b[i]);
}

你的函数数组只有4项,所以b[4]是未定义的。而不是在点击处理程序中引用b,使其成为点击处理程序本身:

elems.eq(i).on('click', b[i]);

通过这样做,i的值将在循环的每次迭代中检查,而不是在单击元素时检查(此时其值应该始终是4)。

问题是,在您的循环中,您设置为click处理程序的函数都共享相同的i值。循环后,i的值将变为4,因此每个函数将尝试调用不存在的b[4]

您需要为每个函数创建一个新的作用域,以便i值都是不同的。

for(var i = 0; i < b.length; i++){
    (function(i){
        $('.class').eq(i).bind('click', function(){
            b[i]();
        });
    }(i));
}

您也可以直接将数组中的函数设置为click处理程序。

for(var i = 0; i < b.length; i++){
    $('.class').eq(i).bind('click', b[i]);
}