Javascript变量范围问题

Sac*_*hin 5 javascript variables jquery scope

我在使用javascript解决范围问题时遇到问题.我有一个数组,dog []是从JSON定义的,我需要从嵌套函数内部访问.

function blah(json) {
 for (var u = 0; u < json[0][1][u].length; u ++ ) {
    var dog = 'k' + json[0][1][u].doggies;
    console.log(dog); // prints array of doggie strings
    $('#puppy').click(function(dog) {    // dog is passed in the function
       console.log(dog); // Syntax error, unrecognized expression: #[object Object]
       $('#' + dog).css('display, 'none');
     });
   }
 }
Run Code Online (Sandbox Code Playgroud)

当我不把狗传递到点击功能时:我得到:

 $('#puppy').click(function() {
  console.log(dog) // (12)  main.js:122k4c812e3a7275e10331000000 - this is the last value in the array - from safari console
  $('#' dog).css('display', 'none);
   }
Run Code Online (Sandbox Code Playgroud)

有没有人有任何建议让每个元素都传递给click函数?或者我是否正确地调用css方法来隐藏这些div?

str*_*ger 4

问题1

闭包绑定整个函数的范围,而不是单个变量或值。

以这段代码为例:

function foo() {
    var i, func;

    for (i = 0; i < 10; ++i) {
        if (i == 0) {
            func = function () {
                alert(i);
            }
        }
    }

    func();
}

foo();
Run Code Online (Sandbox Code Playgroud)

您可能期望foo引起0警报。i然而,自分配给的函数func创建以来,的值已发生变化;呼叫func警报“10”。

这是说明这个概念的另一个例子:

function foo() {
    var i = 42;

    function func() {
        alert(i);
    }

    for (i = 0; i < 10; ++i) {
        // do nothing
    }

    func();
}

foo();
Run Code Online (Sandbox Code Playgroud)

尝试找出将发出警报的内容,并运行代码进行测试。

问题2

第二个问题是变量绑定在函数作用域(而不是您期望的块作用域)。

采取这个代码:

function foo() {
    var i;

    for (i = 0; i < 10; ++i) {
        var j = i;
    }

    alert(j);
}

foo();
Run Code Online (Sandbox Code Playgroud)

您可能期望此代码会警告“未定义”,抛出运行时错误,甚至抛出语法错误。然而,“10”被警告。为什么?在 JavaScript 中,上面的代码被有效地翻译成:

function foo() {
    var i;

    var j;

    for (i = 0; i < 10; ++i) {
        j = i;
    }

    alert(j);
}

foo();
Run Code Online (Sandbox Code Playgroud)

从这个例子应该更清楚,“10”确实被警告了。

解决方案

那么你如何解决你的问题呢?最简单的方法是改变你的逻辑:不是为每只狗附加一个事件处理程序,而是为每个狗集合攻击一个事件处理程序。例如:

function blah(json) {
    $('#puppy').click(function () {
        var u, dog;

        for (u = 0; u < json[0][1][u].length; u++) {
            dog = 'k' + json[0][1][u].doggies;

            console.log(dog);

            $('#' + dog).css('display', 'none');
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

如果您对现有代码的“正确”转换感兴趣(即具有相同的行为,除了修复错误),我也可以给您一个例子。然而,我上面给出的解决方案是一个更好的解决方案,并且可以产生更干净的代码。