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

Mar*_*ark 12 javascript variables scope

我有一些像这样的代码:

if (condition) {
var variable = blah;
}

if (differentcondition) {
var variable = blah;
}
Run Code Online (Sandbox Code Playgroud)

它是否正确?

我假设如果条件不返回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
    }

});
Run Code Online (Sandbox Code Playgroud)

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

这适用于我,但它是否正确?

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

实际上我也想说某些条件是相互排斥的,而某些条件则不是.

我应该如何构建这个?

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

Bre*_*ton 32

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

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

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

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


Dan*_*ert 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);
}
Run Code Online (Sandbox Code Playgroud)

  • +1.此外,你应该将你的变量命名为有意义的东西,而不仅仅是"变量"(无论如何都是坏的,因为它可能是某些语言中的保留关键字). (2认同)

Jas*_*wig 6

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

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

    var x = 4;
}
foo();
alert(x); // will alert 2
Run Code Online (Sandbox Code Playgroud)

第一个警报实际上会说未定义.为什么?因为函数中出现的所有变量初始化在函数开始时都被初始化为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
        }

});
Run Code Online (Sandbox Code Playgroud)