理解闭包中的变量错误?

时间:2015-10-03 03:25:39

标签: javascript function closures

我正在学习闭包。这个例子是作为一个闭包时常见的错误:

function assignTorpedo(name, passengerArray) {
    var torpedoAssignment;
    for (var i = 0; i<passengerArray.length; i++) {
        if (passengerArray[i] == name) {
            torpedoAssignment = function() {
                alert("Ahoy, " + name + "!\n" +
                "Man your post at Torpedo #" + (i+1) + "!");
            };
        }
    }
    return torpedoAssignment;
}

由于for循环在返回闭包之前完成,因此i值将与名称不匹配。所以,我理解循环在返回之前继续。

我的问题来自于此,一个正确做事方式的例子:

function makeTorpedoAssigner(passengerArray) {
    return function (name) {
        for (var i = 0; i<passengerArray.length; i++) {
            if (passengerArray[i] == name) {
                alert("Ahoy, " + name + "!\n" +
                "Man your post at Torpedo #" + (i+1) + "!");
            }
        }
    };
}

我不明白为什么在上面的例子中,for循环在第一次找到匹配时也不会继续,这会导致另一个不匹配的i。我知道返回会停止一个函数,但是我不理解返回和第一个匹配之间的联系,因为它们不会一起发生(直观地)。我理解代码知道如果返回在if函数或for循环中,就会停止。

2 个答案:

答案 0 :(得分:0)

  

我不明白为什么在上面的例子中,for循环在第一次找到匹配时也不会继续

会的。

  

这将导致另一个不匹配的我。

它不会,因为它每次都会检查if (passengerArray[i] == name)。但这很浪费;这是一个不寻常的修复。更好的方法是传递索引:

function makeTorpedoAssigner(passengerArray, i) {
    return function (name) {
        alert("Ahoy, " + name + "!\n" +
              "Man your post at Torpedo #" + (i+1) + "!");
    };
}

function assignTorpedo(name, passengerArray) {
    for (var i = 0; i<passengerArray.length; i++) {
        if (passengerArray[i] == name) {
            return makeTorpedoAssigner(passengerArray, i);
        }
    }
}

答案 1 :(得分:0)

这里发生的是:

  

assignTorpedo()每次都会返回一个基于名称的函数   检查passengerArray中的名称并返回一个函数,但之前   assignTorpedo可以返回torpedoAssignment,我将拥有的值   更改为最后一个值(passengerArray的length-1),因为循环将继续执行。

char

正确的方法解释:

  

在这里,您将返回一个函数,该函数采用名称并检查每个函数   在数组中的时间,这里的闭包概念即使如此   函数(name)被返回,它会记住passengerArray(如果你   会看到passengerArray每次都没有通过,但没有错误   抛出。这是关闭。)

#include <Ethernet.h>
#include <SPI.h> m 
#include "kSeries.h"

kSeries K_30(8,9);


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 229 };
byte gateway[] = { 192, 168, 1, 1 };
byte server[] = { 192, 168, 1, 138 }; // alamat host Server
String location = "GET http://192.168.1.138/SIMON/datasetiapdetik.php?";
//String location = "POST /alvin/datasetiapdetik.php?";
String host = "Host:  192.168.1.138";

EthernetClient client;

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  Serial.println("connecting...");
}

void loop()
{
   double co2 = K_30.getCO2('p');
  // Print the value on Serial
  Serial.print(co2);
  Serial.println("ppm \t");



String data;
  data+="";
  data+="device=arduino";
  data+="&A0=";data+=co2;
  data+="&submit=Submit";
  Serial.print(data);
while (client.connect(server, 80)) {
    Serial.println("Sending data..");


    //lokasi halaman atau form 
    client.print(location);
    client.print(data);
    client.println("HTTP/1.1");
    client.println(host);
    //client.println("Connection: close");
    //char web=client.read();
    Serial.print(location);
    Serial.print(data);

    client.stop();  
  }
  /*
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  delay(50);
  }*/
  delay(2000);
}