在if块中定义JavaScript变量有什么问题?

时间:2009-07-22 01:13:42

标签: javascript variables scope

我有一些像这样的代码:

if (condition) {
var variable = blah;
}

if (differentcondition) {
var variable = blah;
}

这是对的吗?

我假设如果条件没有返回true,则不会分配变量。

JSLint不断告诉我,变量已经定义。

我这样做错了吗?

感谢。

好的,这是我的实际用例,我正在做这样的事件委托:

$("#container").click(function (event){ 

    if ($(event.target).is('img.class1')) {
        var imagesrc = $(event.target).attr('src');
        // Do something with imagesrc
    }

    if ($(event.target).is('img.class2')) {
        var imagesrc = $(event.target).attr('src');
        // Do something with imagesrc
    }

    // This condition is mutually exclusive to the above 2
    if ($(event.target).is('img.class3')) {
        var imagesrc = $(event.target).attr('src');
        // Do something with imagesrc
    }

    // This condition is mutually exclusive to 1 and 2 but not to 3
    if ($(event.target).is('img.class4')) {
        var imagesrc = $(event.target).attr('src');
        // Do something with imagesrc
    }

});

实际上这两个类并不相互排斥。

这对我有用,但它是否正确?

答案非常有用,但我仍然不明白我应该如何在这里设置变量。

实际上我也想说某些条件是互斥的,某些条件不是。

我应该如何构建这个?

我可能应该从一开始就使用这个例子。

5 个答案:

答案 0 :(得分:31)

因为javascript有一些名为“Hoisting”的东西会使你的代码做的事情看起来不像它应该做的那样。基本上,这意味着javascript解释器会将所有var声明(无论它们在函数体中的位置)移动到函数体的顶部。然后它会将所有函数定义移动到顶部,就在所有变量之下。然后它将完成编译功能。

将var放在if语句中并不违反语言的“规则”,但这意味着,由于var提升,无论if语句的条件是否满足,都将定义var。

请记住,提升不包括赋值,正如其他人所指出的那样,var声明将被移动到顶部,并且保留未定义,直到稍后分配它们为止。

这是一个当时看起来一个好主意的功能的例子,但事实证明它更令人困惑而不是有用。

答案 1 :(得分:12)

这是因为在JavaScript中,变量在功能块中只有不同的范围。与其他语言不同,if-blocks在JavaScript中没有不同的范围。

在您的情况下,JSLint会告诉您变量已经定义,因为两个条件都可能为真,在这种情况下您将覆盖变量。

以下是范围在JavaScript中的工作原理示例:

function Something() {
    var thing1 = "hello";

    (function() {
        var thing2 = "world";
    })();

    // This line will throw a ReferenceError because "thing2" is not defined in this scope
    // It only exists within the scope of the function executed above
    alert(thing1 + thing2);
}

function SomethingElse() {
    var thing1 = "hello";

    if(true) {
        var thing2 = "world";
    }

    // This line will work because thing2 is not limited to the if-block
    alert(thing1 + thing2);
}

答案 2 :(得分:6)

只有函数才能创建内部范围。它在这个例子中变得更加毛茸茸。

var x = 2;
function foo() {
    alert(x); // will alert undefined?!?

    var x = 4;
}
foo();
alert(x); // will alert 2

第一个警报实际上会说未定义。为什么?因为函数中出现的所有变量初始化在函数开始时被初始化为undefined 。这就是为什么Crockford说要尽早初始化所有变量。

所以你的代码应该是这样的:

$("#container").click(function (event){ 
        var imagesrc;
        if ($(event.target).is('img.class1')) {
                imagesrc = $(event.target).attr('src');
                // Do something with imagesrc
        }

        if ($(event.target).is('img.class2')) {
                imagesrc = $(event.target).attr('src');
                // Do something with imagesrc
        }

        // This condition is mutually exclusive to the above 2
        if ($(event.target).is('img.class3')) {
                imagesrc = $(event.target).attr('src');
                // Do something with imagesrc
        }

        // This condition is mutually exclusive to 1 and 2 but not to 3
        if ($(event.target).is('img.class4')) {
                imagesrc = $(event.target).attr('src');
                // Do something with imagesrc
        }

});

答案 3 :(得分:0)

两个if条件是否相互排斥?也许你想使用“else”控制结构:

if (condition) {
    var variable = blah;
}
else if (differentcondition) {
    var variable = blah;
}

这意味着如果第一个条件为真,那么代码的第二部分将永远不会被执行。

一般来说,最好在它们正在使用的结构中声明变量。如果变量应该只存在于if语句中,则声明它没有问题,否则,将它移到外面就像这样:

var variable;
if (condition) {
    variable = blah;
}
else if (differentcondition) {
    variable = blah;
}
// continue to use variable here...

注意:如果您使用不带else的单独ifs,则需要先将变量设置为默认值。

答案 4 :(得分:0)

  

我应该如何构建这个?

在这种情况下,看起来嵌套条件会更好:

$("#container").click(function (event) {
    if ($(event.target).is('img')) {
        var imagesrc = $(event.target).attr('src');

        if ($(event.target).is('.class1')) {
            // Do something with imagesrc
        }

        if ($(event.target).is('.class2')) {
            // Do something with imagesrc
        }

        // This condition is mutually exclusive to the above 2
        if ($(event.target).is('.class3')) {
            // Do something with imagesrc
        }

        // This condition is mutually exclusive to 1 and 2 but not to 3
        if ($(event.target).is('.class4')) {
            // Do something with imagesrc
        }
    }
});

或者更好地使用jQuery的事件委托:

$("#container").on("click", "img", function (event) {
    var imagesrc = $(this).attr('src');

    if ($(this).is('.class1')) {
        // Do something with imagesrc
    }

    if ($(this).is('.class2')) {
        // Do something with imagesrc
    }

    // This condition is mutually exclusive to the above 2
    if ($(this).is('.class3')) {
        // Do something with imagesrc
    }

    // This condition is mutually exclusive to 1 and 2 but not to 3
    if ($(this).is('img.class4')) {
        // Do something with imagesrc
    }
});