为什么这个简单的循环工作不像预期的那样?

时间:2015-11-13 01:29:27

标签: javascript loops

有人可能希望以下内容打印出abc

var i, rowName;
for (i = 0; i < 3; i++, rowName = ['a', 'b', 'c'][i]) {
    console.log(rowName);
}
但是,相反,它打印出undefinedbc。为什么呢?

澄清:我知道如何使这项工作;我感到好奇的是为什么以上都不起作用。

4 个答案:

答案 0 :(得分:5)

它打印stringundefinedb的原因是因为for loop的工作方式。

c

让我们分解你的for循环。

初始化for (initialization; condition; final expression)

条件i = 0

最终表达i < 3

首次输入循环时,i++, rowName = ['a', 'b', 'c'][i]设置为i。这是初始化步骤。然后检查条件步骤0。这在每次迭代之前完成,以决定是否继续循环。在每个循环之后,将评估最终表达式。在您的示例中,在根据当前索引将i < 3设置为i中的元素之前,您需要增加rowName

在您的情况下,在第一次迭代中,['a', 'b', 'c']rowName,因为尚未评估最终表达式。之后的每次迭代都表现得如您所期望的那样,因为最终表达式之前已经被评估过了。

答案 1 :(得分:2)

如果你想做一个棘手的单行for循环风格,&#34;正确&#34;语法是:

var array = ['a', 'b', 'c'];
for (var i = 0, rowName; rowName = array[ i++ ]; ) {
    console.log(rowName);
}

注意;循环声明的结尾for。在;之后,技术上是一个空的陈述,这是你通常会做i++的地方。

在这种情况下,&#34;条件&#34; for循环正在利用Javascript赋值运算符。如果你有这样的代码:

var a;
if( a = 1 ) { // Note this is assignment = not comparison ==
    console.log('true');
}

记录&#34; true&#34;。为什么?因为在表达式中,a = 1实际上返回1。并且1是&#34; truthy,&#34;意味着它在布尔上下文中评估为true,如if语句。

如果你的价值是假的,反之亦然:

var a;
if( a = 0 ) {
    console.log('true');
}

它不会记录,因为a = 0返回0(以及将{0分配给a)。 0是假的。

这种糟糕的for循环语法仅适用于某些条件:

  • 如果任何数组元素是&#34; falsey&#34; (nullundefined""等)它会过早地终止循环,因为运营商的工作方式如上所述。
  • 这假设您不关心循环索引i。对于循环的每次迭代,它将偏离1,因为i++在<{strong> for块之前执行。也就是说,第一次执行for正文时,i将为1,而不是其声明的起始值为0.
  • 此模式的唯一好处是节省了几个字节。由于上述两个陷阱,它通常不会在现实世界中使用。

答案 2 :(得分:0)

我想你想要这个?

var i, rowName;
for (i = 0; i < 3; i++){
    rowName = ['a', 'b', 'c'][i];
    console.log(rowName);
}

答案 3 :(得分:0)

您在循环的每个步骤重新分配rowName,并开始undefined for(var i=0,rowName=['a','b','c'],l=rowName.length; i<l; i++){ console.log(rowName[i]); } 。以下是您可以做的事情:

var rowName = ['a', 'b', 'c'];
for(var i=0,l=rowName.length; i<l; i++){
  console.log(rowName[i]);
}

或类似的东西:

for(assign; test; execute)

真正的问题是execute内的第三个条件不会test直到满足循环的test。如果execute失败,则test永远不会发生。如果execute通过struct TCB { int thread_id; //number representing what thread this TCB belongs to int status; //running = 0, ready = 1, terminated = 2 int executionInfo; //number of time this thread has been run (incremented every time thread's context is restored) char* SP; //SP used to store and restore context (stw RA, 0(SP) -- stw R1, 4(SP)) }; void mythread_create(int thread_id){ //use malloc to initialize stack space char* stack; stack = (char *) malloc(4000 * sizeof(char)); //create and initialize TCB for thread struct TCB *TCB; TCB.thread_id = thread_id; TCB.status = 1; TCB.executionInfo = 0; TCB.SP = } 确实在第一次循环后开始。