Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
模块内的Javascript作用域问题_Javascript - Fatal编程技术网

模块内的Javascript作用域问题

模块内的Javascript作用域问题,javascript,Javascript,当在下面的代码中声明时,$sessionTimeLeft在updateSession()中被访问时是未定义的。但是当我在initiate()中移动$sessionTimeLeft声明和赋值时,我得到了正确的jQuery对象。由于闭包的原因,我想我可以在initiate()中声明$sessionTimeLeft时访问它。但是为什么$sessionTimeLeft超出了我原始代码的范围 var session = (function SessionManager() { var timeLeft

当在下面的代码中声明时,
$sessionTimeLeft
updateSession()中被访问时是未定义的。但是当我在
initiate()
中移动
$sessionTimeLeft
声明和赋值时,我得到了正确的jQuery对象。由于闭包的原因,我想我可以在
initiate()
中声明
$sessionTimeLeft
时访问它。但是为什么
$sessionTimeLeft
超出了我原始代码的范围

var session = (function SessionManager() {
  var timeLeftInMs;
  var timeLeftInMin;
  var delay; // in ms
  var $sessionTimeLeft = $('#dcSessionTimeLeft');

  /* Set up the module by setting the timeout and delay time. */
  function initiate(_timeout, _delay) {
    timeLeftInMin = _timeout;
    timeLeftInMs = timeLeftInMin * 60 * 1000;    
    delay = _delay; // delay in ms      

    setInterval(updateSession, delay);
  }

  function updateSession() {
    timeLeftInMs -= delay;
    timeLeftInMin = timeLeftInMs / 60000; // convert ms to min.              

    $sessionTimeLeft.text(timeLeftInMin);
  }

  var publicAPI = {
    initiate: initiate
  };

  return publicAPI;
})();

session.initiate(30,1000);

在这种情况下,闭包也应该绝对有效。此代码无法工作的原因是您没有正确调用会话函数。请记住,此函数返回一个带有函数initiate的对象

代码的最后一行应该是

session.initiate(30,1000);
这应该行得通。为了重现我使用的问题,我使用了node。我将$sessionTimeLeft变量更改为字符串hello,并在updateSession函数中测试它是否仍然可以访问。我的代码是

var session = (function SessionManager() {
  var timeLeftInMs;
  var timeLeftInMin;
  var delay; // in ms
  var $sessionTimeLeft = "Hello";

  /* Set up the module by setting the timeout and delay time. */
  function initiate(_timeout, _delay) {
    timeLeftInMin = _timeout;
    timeLeftInMs = timeLeftInMin * 60 * 1000;
    delay = _delay; // delay in ms

    setInterval(updateSession, delay);
  }

  function updateSession() {
    timeLeftInMs -= delay;
    timeLeftInMin = timeLeftInMs / 60000; // convert ms to min.

    console.log($sessionTimeLeft);
  }

  var publicAPI = {
    initiate: initiate
  };

  return publicAPI;
})();

session.initiate(30,1000);
我得到的结果是

Hello
Hello
Hello
Hello
Hello

每1秒一次

这里的问题是,
#dcSessionTimeLeft
在您尝试访问它时可能尚未加载。因此,确保加载的一种方法是将您的代码包装为:


session.initiate(301000)
在分配给
$sessionTimeLeft
时加载了
\dcSessionTimeLeft
?请提供代码来重现该问题。如果是真的,这是一个极好的问题。我不知道为什么人们在贬低我it@TejaswiSharma这可能很有趣。但这也可能是因为在创建模块时,id为dcSessionTimeLeft的元素不存在
$(function() {
  var session = (function SessionManager() {
  var timeLeftInMs;
  var timeLeftInMin;
  var delay; // in ms
  var $sessionTimeLeft = $('#dcSessionTimeLeft');

  /* Set up the module by setting the timeout and delay time. */
  function initiate(_timeout, _delay) {
    timeLeftInMin = _timeout;
    timeLeftInMs = timeLeftInMin * 60 * 1000;    
    delay = _delay; // delay in ms      

    setInterval(updateSession, delay);
  }

  function updateSession() {
    timeLeftInMs -= delay;
    timeLeftInMin = timeLeftInMs / 60000; // convert ms to min.              

    $sessionTimeLeft.text(timeLeftInMin);
  }

  var publicAPI = {
    initiate: initiate
  };

  return publicAPI;
  })();

  session.initiate(30,1000);
});