功能只执行一次

时间:2016-03-06 03:40:51

标签: javascript html

所以我有一个名为lines的列表设置,它将每一行设置为分开。然后这些被发送到另一个名为rdline()的函数中读取它。我已经设置了一个警报,以查看通过它的内容,并且只有在阵列中有多个条目时才会发出警报。



var ms = false;
var ss;
var c;
var lc;
var lines = [];
var currset;
var win;
var sendline = 0;
var op = function() {
  document.getElementById('rd').innerHTML = "Reading...";
  ss = document.getElementById('t').innerHTML;
  c = document.getElementById('t').innerHTML;
  document.getElementById('t').innerHTML = "";
  lc = 0;
  lines = [];
  currset = [];
  setLines(c);
}
var setLines = function(cont) {
  for (i = 0; i < cont.length; i++) {
    if (cont[i] == ";") {
      lines[lc] = currset.join("").replace("<br>", "") + " ";
      lc++;
      currset = [];

    } else {
      currset[i] = cont[i];
    }
  }
  for (i = 0; i < lines.length; i++) {
    rdline(lines[i])
  }
  
}
var rdline = function(parg) {
  //EXECUTING ONCE!
  alert(parg)
  //the rest should be fine
  var pl = [];
  var toplace = [];
  var pcount = 0;
  for (i = 0; i < parg.length; i++) {
    if (parg[i] == " ") {
      pl[pcount] = toplace.join("");
      pcount++;
      toplace = [];
    } else {
      toplace[i] = parg[i];
    }
  }
  //functions
  if (pl[0] == "$setupmemes") {
    ms = true;
    win = window.open("", "", "height=800", "width=800")
  }
  if (ms == true) {
    if (pl[0] == "expand") {
      win.document.write('dongs')
    }
  }
  document.getElementById('t').innerHTML = ss;
}
&#13;
code {
  width: 100%;
  height: 100vh;
  border: none;
  background: black;
  color: white;
  font-size: 150%;
  font-family: sans-serif;
  display: inline-block;
}
&#13;
<button onClick='op()'>Run</button>
<span id='rd'></span>
<br />
<br />
<code contenteditable="true" id='t'></code>
&#13;
&#13;
&#13; 运行代码段并输入:

$ setupmemes; 扩大;

1 个答案:

答案 0 :(得分:0)

问题在于,您的setlines函数中有一个循环,它使用i作为计数器,但您没有使用var来初始化它,这使它成为一个全局变量:

function setLines(cont) {
  // RIGHT HERE, YOU ARE NOT DECLARING i WITH var
  for (i = 0; i < cont.length; i++) {
    if (cont[i] == ";") {
      lines[lc] = currset.join("").replace("<br>", "") + " ";
      lc++;
      currset = [];

    } else {
      currset[i] = cont[i];
    }
  }

  // RIGHT HERE, YOU ARE NOT DECLARING i EITHER, SO THE PREVIOUS
  // i VALUE IS RESET TO ZERO (NOT A PROBLEM YET, BUT IT WILL BE)
  for (i = 0; i < lines.length; i++) {
    rdline(lines[i])
  }
}

因此,i成为全局变量。然后,在rdline函数中,您还有另一个循环,它也使用i,但是没有声明:

function rdline(parg) {
  //EXECUTING ONCE!
  alert(parg)
  //the rest should be fine
  var pl = [];
  var toplace = [];
  var pcount = 0;

  // USE OF GLOBAL i again! i is again reset to zero
  // This loop allows i to go to a higher value than
  // the first loop that sent you to this one!
  for (i = 0; i < parg.length; i++) {
    if (parg[i] == " ") {
      pl[pcount] = toplace.join("");
      pcount++;
      toplace = [];
    } else {
      toplace[i] = parg[i];
    }
  }

这个循环使用相同的全局i变量作为第一个允许i增加到36的变量(第一次调用rdlinerdline完成并返回第一个循环,i大于lines.length,因此第一个循环终止。

解决方案是始终声明循环变量(最好在循环中),如:

       // Notice the var?
       for(var i = 0; ...

在同一范围内需要多个循环时,使用不同的循环变量。将函数rdline中的循环变量更改为其他名称,并在该循环中将var更改为:

       // When multiple loops exist in the same scope,
       // always use a different counter for each loop!
       for(var x = 0; ...

请记住,在JavaScript中,默认情况下您没有块级范围(顺便说一句,您可以使用新的let关键字创建块级范围)。当两个(或多个)循环使用同一范围内的相同循环变量时,在未声明的函数中设置的变量(无var)变为全局且没有块范围(默认情况下)循环将导致计数器更改该范围内的所有循环。