这适合我的循环吗?

时间:2018-12-28 11:52:34

标签: javascript loops for-loop scope let

我写了一个简单的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

5 个答案:

答案 0 :(得分:1)

您的示例很糟糕,因为您的循环在2之后不进行计数。因此,如果您的循环看起来像i <= 3

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

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

答案 1 :(得分:0)

  1. 在基于非循环的代码中,i不在声明的同一时刻执行,因此{ let i = 0; i = 1; i = 2; printNumTwo = function () { return i; } i = 3; } console.log(printNumTwo());的值在执行之前已更新,因此返回值3。 li>

i

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

return

注意for循环中的i <= 3中断了循环的进一步执行,因此即使您的第一个代码将for (let i = 0; i <= 3; i++) { if (i === 2) { printNumTwo = function() { return i; }; } } console.log(printNumTwo())作为其中断条件,它将返回2。

optional

答案 2 :(得分:0)

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

printNumTwo = function() {
    return num;
}

在模拟循环中:

i = 2;
num = i;
printNumTwo = function() {
    return num;
}
i = 3;

答案 3 :(得分:0)

"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;

答案 4 :(得分:0)

我很感谢我对问题的所有回答。所有这些都指向一个函数在被调用时如何处理被调用和创建的环境的情况。我在“ Eloquent JavaScript”一书中读到了这个有用的解释,并认为分享它会很好,

“一个好的思维模型是认为函数值既包含其主体中的代码,又包含创建它们的环境。调用该函数时,函数主体将看到其创建环境,而不是其中的环境。被称为。” 〜Eloquent_JavaScript /关闭