从函数返回时,for循环未定义

时间:2018-01-29 14:33:24

标签: javascript for-loop return-value

基本上,我有一个表单提交所选的电台项目。为了检测所选项目,我使用了for-each循环(标准循环)。

如您所见,我能够返回一个具有testVar值的对象,以便在另一个函数构造函数中使用。但是,emotionSelected的值变得不确定。

https://codepen.io/aguerrero/pen/PQopxw

var diaryUI = (function() {

    var emotionSelected, emotionList, testVar;

    emotionList = document.getElementsByName("emotion");

    for (var i = 0; i < emotionList.length; i++) {
        if (emotionList[i].checked) {
            emotionSelected = emotionList[i].value;
            break;
        }
    }

    testVar = "hello";

    return {
        getInput: function() {
            return {
                emotion: emotionSelected,
                test: testVar
            }
        }
    }

})();


var mainController = (function(diaryUICtrl) {

    var addEntry = function() {

        var input = diaryUICtrl.getInput();
        console.log(input);
    }

    document.getElementById("submit-entry").addEventListener("click", addEntry);


})(diaryUI);

但是,如果我在方法getInput中移动for-each循环,那么它可以工作。

可能出现什么问题?

3 个答案:

答案 0 :(得分:1)

赋值运算符dairyUI之后的函数立即运行,这可能是在加载DOM之前。您可能希望在getInput运行时执行DOM选择,顺便说一下,这可以更简洁地完成。

var diaryUI = (function() {

    var testVar = "hello";

    return {
      getInput: function() {
        return {
          emotion: (document.querySelector("[name=emotion]:checked") || {}).value,
          test: testVar
         }
      }
    }
})();

答案 1 :(得分:1)

您正在使用名为 Self-Invoking-Function 的内容,因此,在您真正提交表单之前,您的初始化对象正在执行。

(function () {
    // body of the function
}());
  

上面的匿名函数将在定义后立即调用。自调用函数的好处是它们使我们能够执行一次代码而不会混淆全局命名空间(不声明任何全局变量)。 Reference

运行此代码段以查看代码如何立即执行函数diaryUI

&#13;
&#13;
var diaryUI = (function() {
    var emotionSelected, emotionList, testVar;
    emotionList = document.getElementsByName("emotion");
    for (var i = 0; i < emotionList.length; i++) {
      console.log(emotionList[i].checked);
      if (emotionList[i].checked) {
        emotionSelected = emotionList[i].value;
        break;
      }
    }
    testVar = "hello";
    return {
      getInput: function() {
        return {
          emotion: emotionSelected,
          test: testVar
        }
      }
    }
  }

)();
var mainController = (function(diaryUICtrl) {
    var addEntry = function() {
      var input = diaryUICtrl.getInput();
      console.log(input);
    }
    document.getElementById("submit-entry").addEventListener("click", addEntry);
  }

)(diaryUI);
&#13;
<label for="emotion"></label>
<input type="radio" name="emotion" value="Happy" id="Happy"> Emotion 1<br>
<input type="radio" name="emotion" value="Sad" id="Sad"> Emotion 2<br>
<input type="radio" name="emotion" value="Neutral" id="Neutral"> Emotion 3
<br><br>
<a href="#" id="submit-entry">Submit Diary</a>
&#13;
&#13;
&#13;

请参阅?您的代码在开始时立即执行。

您需要重新思考宣布/实施职能的方式。

这种方法可以帮助您,但您需要决定是否必须立即执行该代码

&#13;
&#13;
var diaryUI = function() {
    var emotionSelected, emotionList, testVar;
    emotionList = document.getElementsByName("emotion");
    for (var i = 0; i < emotionList.length; i++) {
      console.log(emotionList[i].checked);
      if (emotionList[i].checked) {
        emotionSelected = emotionList[i].value;
        break;
      }
    }
    testVar = "hello";
    
        return {
          emotion: emotionSelected,
          test: testVar
        }
  }

var mainController = (function(diaryUICtrl) {
    var addEntry = function() {
      var input = diaryUI();
      console.log(input);
    }
    document.getElementById("submit-entry").addEventListener("click", addEntry);
  }
)();
&#13;
<label for="emotion"></label>
<input type="radio" name="emotion" value="Happy" id="Happy"> Emotion 1<br>
<input type="radio" name="emotion" value="Sad" id="Sad"> Emotion 2<br>
<input type="radio" name="emotion" value="Neutral" id="Neutral"> Emotion 3
<br><br>
<a href="#" id="submit-entry">Submit Diary</a>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

即使发生了点击事件,您也会立即调用diaryUIIIFE)。

我会将diaryUI作为函数引用传递,并在单击处理程序中调用它。

顺便说一句,如果函数位于等号(=)的右侧,则无需用括号括起函数。这已经是一种表达。

运行示例:

&#13;
&#13;
var diaryUI = function() {
  var emotionSelected, emotionList, testVar;

  emotionList = document.getElementsByName("emotion");

  for (var i = 0; i < emotionList.length; i++) {
    if (emotionList[i].checked) {
      emotionSelected = emotionList[i].value;
      break;
    }
  }

  testVar = "hello";

  return {
    getInput: function() {
      return {
        emotion: emotionSelected,
        test: testVar
      };
    }
  };
};

var mainController = (function(diaryUICtrl) {
  var addEntry = function() {
    var ctrl = diaryUICtrl();
    var input = ctrl.getInput();
    console.log(input);
  };

  document.getElementById("submit-entry").addEventListener("click", addEntry);
})(diaryUI);
&#13;
<label for="emotion"></label>
      <input type="radio" name="emotion" value="Happy" id="Happy"> Emotion 1<br>
      <input type="radio" name="emotion" value="Sad" id="Sad"> Emotion 2<br>
      <input type="radio" name="emotion" value="Neutral" id="Neutral"> Emotion 3
<br><br>
<a href="#" id="submit-entry">Submit Diary</a>
&#13;
&#13;
&#13;