Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在for循环内绑定侦听器:变量范围错误理解_Javascript_Jquery_Scope - Fatal编程技术网

Javascript 在for循环内绑定侦听器:变量范围错误理解

Javascript 在for循环内绑定侦听器:变量范围错误理解,javascript,jquery,scope,Javascript,Jquery,Scope,我有一个可变范围的问题,我不明白为什么会发生这种情况,以及如何消除它: var items = ['foo', 'bar']; for (var index in items) { var item = items[index]; var selector = '.'+item+'-class'; $(selector).bind('click', function() { console.log("clas

我有一个可变范围的问题,我不明白为什么会发生这种情况,以及如何消除它:

    var items = ['foo', 'bar'];
    for (var index in items) {
        var item = items[index];
        var selector = '.'+item+'-class';
        $(selector).bind('click', function() {
            console.log("class: "+$(this).attr('class'));
            console.log("selector: "+selector);
            console.log("item: "+item);
        });
    }
认为此代码通过以下HTML自行执行:

<div class="foo-class">Foo</div>
<div class="bar-class">Bar</div>
Foo
酒吧
单击“Foo”会在第一行中回显正确的类(即“Foo类”),但下面的选择器和项目名称与bar相关。我认为问题在于循环的第二次迭代重置了第一次迭代中使用的变量

我认为循环中的声明应该在这个级别清楚地声明它们的范围。我错了吗?为什么?我怎样才能修好它

我不是在寻找解决办法,我想要一些干净的东西,更好地理解javascript变量作用域机制

给你


谢谢

这些for循环总是一样的(谷歌It)。JavaScript没有块作用域,而是函数作用域,因此当单击一个项时,一个变量
选择器
具有上次循环运行后的值(变量


为了解决这个问题,在循环中需要另一个闭包,它将变量存储在自己的作用域中。这意味着您需要为每个循环运行执行一个函数。

这些for循环总是相同的(谷歌It)。JavaScript没有块作用域,而是函数作用域,因此当单击一个项时,一个变量
选择器
具有上次循环运行后的值(变量


为了解决这个问题,在循环中需要另一个闭包,它将变量存储在自己的作用域中。这意味着您需要为每个循环运行执行一个函数。

这是您的小提琴示例

var items = ['foo', 'bar'];
for (var index in items) {
    (function() {
        var item = items[index]; 
        var selector = '.' + item + '-class';
        $(selector).bind('click', function() {
            console.log("class: " + $(this).attr('class'));
            console.log("selector: " + selector);
            console.log("item: " + item);
        });
    })();
}​
创建匿名函数将为每个定义的变量定义一个新范围


提示:尝试创建一个单独的函数来进行绑定,以保持代码的整洁。

下面是更新的fiddle示例

var items = ['foo', 'bar'];
for (var index in items) {
    (function() {
        var item = items[index]; 
        var selector = '.' + item + '-class';
        $(selector).bind('click', function() {
            console.log("class: " + $(this).attr('class'));
            console.log("selector: " + selector);
            console.log("item: " + item);
        });
    })();
}​
创建匿名函数将为每个定义的变量定义一个新范围


提示:尝试创建一个单独的函数来进行绑定,只是为了让代码更干净。

问题并不是严格意义上的变量范围。匿名函数在触发click事件时运行,而不是在循环中定义它时运行。考虑下面的功能与你的例子相同:

var items = ['foo', 'bar'];

for (var index in items) {
    var item = items[index];
    var selector = '.'+item+'-class';
    $(selector).bind( 'click', test );
}
​
function test() {
    console.log("selector: "+selector);
}

这(希望)说明了发生了什么:函数中的全局变量
选择器在调用函数时,在两种情况下(“bar”)都是相同的。

问题并不是严格意义上的变量范围。匿名函数在触发click事件时运行,而不是在循环中定义它时运行。考虑下面的功能与你的例子相同:

var items = ['foo', 'bar'];

for (var index in items) {
    var item = items[index];
    var selector = '.'+item+'-class';
    $(selector).bind( 'click', test );
}
​
function test() {
    console.log("selector: "+selector);
}
这(希望)演示了正在发生的情况:在调用函数时,函数中的全局变量
selector
,在这两种情况下(“bar”)是相同的


变量“选择器”和“项目”是对存储值的位置的引用,当您单击其中一个htl元素时,这两个元素的值是最后一个循环中的值。

变量“选择器”和“项目”是对存储值的位置的引用,单击其中一个htl元素时,这两个元素的值是最后一个循环中的值。

谢谢,但我怀疑调用test时是否会设置选择器。为什么不设置?这是一个全局变量。对不起,我以为这是一个函数。。。不知道为什么。你说得对。谢谢,但我怀疑在调用测试时是否会设置选择器。为什么不呢?这是一个全局变量。对不起,我以为这是一个函数。。。不知道为什么。你说得对。谢谢你的清楚解释。我不知道这个函数级变量scope+1感谢您的明确解释。我不知道这个函数级变量作用域+1谢谢,已修复并已理解+1谢谢,已修复并已理解+1