Javascript函数中的循环行为奇怪

时间:2012-06-26 01:46:50

标签: javascript for-loop

我的函数

中有以下循环

如果x大于10,我看到它循环,但如果大于10,即使条件y <1,它也会失败。 x满足

function insert(x,y) {

   for (var shift = y; shift < x; shift++) {
      //get into loop for insert (9,2) but not for insert(10,2) 
   }       

}

这是实际的函数,我试图在使用rapheal.js的场景之前可视化插入,它适用于insertBeforeTo(9,2)但是当我尝试insertBeforeTo(10,2)时它不会进入循环。

function insertBeforeTo(whichElementI, insertBeforeI) {

     var twhichElement = blocks[whichElementI];
     blocks[whichElementI].animate({ x: blocks[insertBeforeI].attr('x') }, 1000, ">");
     var shiftplusone = insertBeforeI;
     for (var shift = insertBeforeI; shift < whichElementI; shift++) {

         ++shiftplusone;
         blocks[shift].animate({ x: blocks[shiftplusone].attr('x') }, 1000, ">");// check  value actually changes

     }
}

唐氏选民:心灵解释?

发现问题:在调试时我看到''中的哪个ElementI和insertBeforeI值。所以我假设它将它作为一个字符串,并且nnnnn和paxdiablo正确地指出,它采用字符串而不是int所以它适用于哪个ElementI = 9和insertBeforeI = 2而不是哪个ElementI = 10,insertBeforeI = 2.

所以我使用了unary +运算符,比如+ whichElementI,+ insertBeforeI来解决这个问题。

由于

3 个答案:

答案 0 :(得分:1)

您应首先检查您传入函数的数据类型。

例如,所有这些产生输出:

insert ( 10,   2)
insert (  9,   2)
insert ( '9', '2')

但以下不是:

insert ( '10', '2')

那是因为字符串 '10'实际上小于字符串'2'。通过这种方式,我的意思是在排序或比较时不会对字符串进行数字处理,而是将每个字符单独进行比较,从而导致前12个数字被排序为:

1
10
11
12
2
3
4
5
6
7
8
9

您可以使用以下代码(one of the many on-line JS runners)查看此操作:

function insert(x,y) {
   for (var shift = y; shift < x; shift++) {
      //get into loop for insert (9,2) but not for insert(10,2) 
      document.write('x');
   }       
}
document.write('<br>10,2 as string: '); insert ('10','2');
document.write('<br>9,2 as string: ');  insert ( '9','2');
document.write('<br>9,2 as num: ');     insert (  9,  2);
document.write('<br>10,2 as num: ');    insert ( 10,  2);

输出:

10,2 as string: 
9,2 as string: xxxxxxx
9,2 as num: xxxxxxx
10,2 as num: xxxxxxxx

如果你有一个你想要作为数字处理的字符串,parseInt()是一种方法,例如:

var str42 = '42';
var num42 = parseInt (str42, 10);

答案 1 :(得分:1)

我猜你是在无意中用字符串值而不是数字值来调用你的函数,就是用

insert("9", "2")
insert("10", "2")

...而不是

insert(9, 2)
insert(10, 2)

例如,如果从html元素属性中获取值,则它们将成为字符串。

使用字符串"2" < "9"true,但"2" < "10"false - 它执行字典(字典)订单比较,而不是数字比较。

如果您希望您的功能以任何一种方式工作,那么您可以更改它以将字符串转换为数字(我更喜欢使用unary plus operator来实现此目的):

function insert(x,y) {

   x = +x;
   y = +y;

   for (var shift = y; shift < x; shift++) {
      //get into loop for insert (9,2) but not for insert(10,2) 
   }       

}

答案 2 :(得分:1)

我不知道whichElementI和insertBeforeI的类型是什么,但是将它们转换为数字* 1。这应该有助于控制一些算术。可能还想检查(isNaN(some_var)== false){...}是否为健全性检查。

function insertBeforeTo(whichElementI, insertBeforeI) {

 var twhichElement = blocks[whichElementI];
 blocks[whichElementI].animate({ x: blocks[insertBeforeI].attr('x') }, 1000, ">");
 var shiftplusone = insertBeforeI*1;
 for (var shift = insertBeforeI*1; shift < whichElementI*1; shift++) {
    ++shiftplusone;
    blocks[shift].animate({ x: blocks[shiftplusone].attr('x') }, 1000, ">");// check x value  actually changes

  }
}