Javascript变量范围问题

Javascript变量范围问题,javascript,jquery,variables,scope,Javascript,Jquery,Variables,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')

我无法用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');
     });
   }
 }
是否有人建议将数组中的每个元素都传递到click函数中?
还是我错误地调用css方法来隐藏那些div?

您不能像在jquery click事件中那样将dog值传递给该事件。单击功能签名为:

$(object).click(function(){


});

你不能这样把狗递进来。即使函数需要一个参数,将其命名为dog也会引起问题。您可能需要将dog的值存储在一个更全局的范围内,这样当单击事件发生时,您仍然可以访问它。

为什么不给doggies一个类
。dog
并在单击
#puppy
时隐藏它们

$("#puppy").click(function() {
    $(".dog").hide();
});
<> P>或者因为你的狗的ID似乎从K开始,你可能会考虑这样的事情:

$("#puppy").click(function() {

    // hide everything with ID beginning with 'k'
    $('[id^=k]').hide();
});
问题1 闭包绑定整个函数的作用域,而不是单个变量或值

以这段代码为例:

function foo() {
    var i, func;

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

    func();
}

foo();
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');
        }
    });
}
试着找出什么会被警告,并将代码作为测试运行

问题2 第二个问题是变量绑定在函数范围(而不是您所期望的块范围)

以这个代码为例:

function foo() {
    var i;

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

    alert(j);
}

foo();
函数foo(){
var i;
对于(i=0;i<10;++i){
var j=i;
}
警惕(j);
}
foo();
您可能期望此代码发出“未定义”警报,抛出运行时错误,甚至抛出语法错误。但是,“10”已发出警报。为什么?在JavaScript中,上述代码被有效地转换为:

function foo() {
    var i;

    var j;

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

    alert(j);
}

foo();
函数foo(){
var i;
var j;
对于(i=0;i<10;++i){
j=i;
}
警惕(j);
}
foo();
从这个例子中可以更清楚地看到,“10”确实被警告了

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

function foo() {
    var i, func;

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

    func();
}

foo();
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');
        }
    });
}
函数blah(json){
$('#puppy')。单击(函数(){
var u,狗;
对于(u=0;u
如果您对现有代码的“适当”转换感兴趣(即,除了修复错误外,具有相同的行为),我也可以给您举一个例子。但是,我上面给出的解决方案是一个更好的解决方案,并且代码更干净。

重要注意事项: 你忘记关闭你的报价了。这:

$('#' + dog).css('display, 'none');
应该是:

$('#' + dog).css('display', 'none');

改进的循环: 您的脚本有几个问题。我将集中讨论循环的总体逻辑结构

不要将许多处理程序附加到
。单击()
,只需附加一个使用jQuery的在JSON上迭代的处理程序即可。
.each()
回调的第一个参数是索引号,第二个参数是值。您可以通过命名参数或使用
参数[0]
参数[1]
来使用这两个参数。我在下面展示前一种方法:

出于演示目的,我添加了更多的测试输出:

function blah(json) {
     $('#puppy').click(function() { 

          // iterate over each json[0][1]
        $.each(json[0][1], function(index, value) {

              // Your original 2 lines
            console.log(value);
            $('#' + value).css('display', 'none');

              // This is just test output, so you can see what is going
              // on.
            $("body").append("Number " + index + " is " + value ".<br/>");
        });
     });
}     
函数blah(json){
$('#puppy')。单击(函数(){
//迭代每个json[0][1]
$.each(json[0][1],函数(索引,值){
//你原来的两行
console.log(值);
$('#'+value).css('display','none');
//这只是测试输出,所以您可以看到发生了什么
//开。
$(“正文”)。追加(“数字”+索引+”是“+值”。
); }); }); }
对不起,但是不
json[0][1][u]。长度随着
u
的每次迭代而变化?彼得·阿杰泰,我在回答中已经提到了这一点@罗布斯托,抓得好;不知道那里发生了什么跟踪。。。。但是在本例中,
dog
作为一个参数实际上代表了
事件
,因为它是
中回调的第一个参数;我误解了你的答案。(我漏掉了两个词,这完全失去了意义…我的错!)在
中回调的第一个参数。click()
是发生的
事件,因此您应该从
函数(dog)中删除
dog
{
在您的解决方案中…为了不混淆问题。非常感谢!非常有用的解释。当我睡眠不足较少时,我将更深入地研究您的示例。@Peter Ajtai,感谢您捕捉到这一点。我复制粘贴了原始代码,基本上只交换了两行。我会修复它。与所有人相比,这是一个简单的解决方案else.+1用于将CSS类用作选择器。