这是我的循环的正确等价物吗?

Posted

技术标签:

【中文标题】这是我的循环的正确等价物吗?【英文标题】:Is this the right equivalent for my loop? 【发布时间】:2019-05-26 06:11:56 【问题描述】:

我写了一个简单的 javascript 代码。我的 for 循环迭代一个“let”声明的变量,i 介于 0 和 2 之间。只有当 i == 2 时,才会在循环内声明函数。函数必须返回 i 变量的值。当我从循环外部调用此函数时,该函数返回 i = 2 的值(这对于块范围变量 i 来说很自然。但是,当我将循环代码重写为其非循环等效代码块时,该函数(仍然从块外调用)返回 i = 3 的值。这是怎么回事?

"use strict";
var printNumTwo;

for (let i = 0; i < 3; i++) 
  if (i === 2) 
    printNumTwo = function() 
      return i;
    ;
  

console.log(printNumTwo());     //returns 2

//  loop equivalent

  let i = 0;
  i = 1;
  i = 2;
  printNumTwo = function() 
    return i;
  
  i = 3;

console.log(printNumTwo());     // returns 3

【问题讨论】:

只是为了给下面的答案添加一点样板,您还可以使用自调用匿名函数来返回一个匿名函数其中i 被引用为参数。这样,i 将被隔离到函数的范围内,因此它会记录 2:jsfiddle.net/briosheje/mho6wgxn 此外,你应该看看这个:***.com/questions/762011/… 尝试将你的函数变量更改为const printNumTwo 【参考方案1】:

你的例子很糟糕,因为你的循环在 2 之后没有计数。所以如果你的循环看起来像 i &lt;= 3:

for (let i = 0; i <= 3; i++) 
  if (i === 2) 
    printNumTwo = function() 
      return i;
    ;
  

您将得到与非循环示例完全相同的结果,这是因为 javascript 中的闭包但 return 会中断循环。您的函数正在从外部范围保存对该变量的引用。

【讨论】:

感谢您的回复,但 return 不会破坏循环,它只会破坏函数范围。循环仍然继续执行,直到最后一次迭代。另外,我没有使用 i 【参考方案2】:

这是因为由于非循环环境,您实际上将函数设置为返回值 3。你应该稍微改变一下循环,添加另一个变量,但首先让你的函数看起来像这样:

printNumTwo = function() 
    return num;

在你的模拟循环中:

i = 2;
num = i;
printNumTwo = function() 
    return num;

i = 3;

【讨论】:

【参考方案3】:
    在您的非基于循环的代码中,printNumTwo 不会在其声明的同一点执行,因此i 的值在执行之前会更新,因此返回值 3。


    let i = 0;
    i = 1;
    i = 2;
    printNumTwo = function () 
        return i;
    
    i = 3;

console.log(printNumTwo());
    但如果您运行以下代码,它应该打印 2,因为如果 i 设置为 3,它会在 value 之前执行


    let i = 0;
    i = 1;
    i = 2;
    printNumTwo = (function() 
        console.log(i);
    )()
    i = 3;

注意return in for 循环会中断循环的进一步执行,因此即使您的第一个代码以i &lt;= 3 作为其中断条件,它也会返回 2。

for (let i = 0; i <= 3; i++) 
    if (i === 2) 
        printNumTwo = function() 
          return i;
        ;
    

console.log(printNumTwo())

【讨论】:

【参考方案4】:
"use strict";
var printNumTwo;

for (let i = 0; i < 3; i++) 
    printNumTwo = function (i) 
      // when references 'i' in this function, 'i' goes to the global scope.
      return i;
    ;
    // set the value 3 for 'i' in the global scope
    i = 3;

console.log(printNumTwo()); // return 3;

试试这个

"use strict";
var printNumTwo;

for (let i = 0; i < 3; i++)  
    printNumTwo = function (i) 
      return i;
    .bind(null, i); // you set the current value as parameter = 0
    i = 3; // i = 3 and break loop

console.log(printNumTwo()); // return 0;

试试这个

"use strict";
var printNumTwo;

for (let i = 0; i < 3; i++)  
    let i = 0;
    i = 1;
    i = 2;
    printNumTwo = function (i) 
      return i;
    .bind(null, i); // you set the current value as parameter = 2
    i = 3; // i = 3 and break loop

console.log(printNumTwo()); // return 2;

【讨论】:

【参考方案5】:

感谢我对我的问题的所有回答。所有这些都指向一个函数在被调用时如何处理它被调用和创建的环境的情况。我在《Eloquent JavaScript》一书中读到了这个有用的解释,觉得可以分享一下,

“一个好的心智模型是将函数值视为包含其主体中的代码和创建它们的环境。当被调用时,函数主体看到它被创建的环境,而不是其中的环境它被称为。” ~ Eloquent_JavaScript/闭包

【讨论】:

以上是关于这是我的循环的正确等价物吗?的主要内容,如果未能解决你的问题,请参考以下文章

hta - Firefox、Chrome 中的等价物 - 这是旧技术吗?

如何在线程之间进行通信以及 Waitforsingleobject() 的等价物

等价类划分法

C++ DWORD 的 C# 等价物是啥?

C 中的 std::copy 等价物

没有循环的 if/else 的 Numpy 等价物