我有一些像这样的代码:
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
}
});
实际上这两个类并不相互排斥。
这对我有用,但它是否正确?
答案非常有用,但我仍然不明白我应该如何在这里设置变量。
实际上我也想说某些条件是互斥的,某些条件不是。
我应该如何构建这个?
我可能应该从一开始就使用这个例子。
答案 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
}
});