【问题标题】:How to deal with nested functions in javascript?如何处理javascript中的嵌套函数?
【发布时间】:2016-02-18 11:20:33
【问题描述】:

这可能是一个初学者的问题,但我面临下一个情况:

$(function f() {

  function test2() {
    //.....
  }

  function GetData() {
    //.....
  }    
  function update() {
    test2();
    GetData();
    //...
  }//end update

  update();

});//end f()

function stop() {
  clearInterval(multipleCalls);
}

function start() {
  multipleCalls=null; //this is a global variable
  setTimeout(update, 1000);
}

当按下按钮并且一切正常时,停止功能会停止图形。按下按钮时,启动功能应重新启动图形。我的猜测是在 start 函数中没有很好地调用更新函数。我怎样才能让一切正常工作?

【问题讨论】:

  • 为什么update() 会调用自己?
  • 并不能直接回答这个问题,但为了将来参考,我总是被告知嵌套函数应该采用 var funcname = function() { ... } 的形式。无论哪种方式都可以,但它更有条理,看起来更干净。
  • 至少应该缩进
  • 你猜对了,update 隐藏在f 中,无法从外部访问。
  • 什么是GetData,它与您的问题有什么关系? test2 呢?还有update?为什么multipleCalls 从未设置?为什么会有multiplecallsmultipleCalls?请检查minimal reproducible example 是什么。

标签: javascript function call invoke


【解决方案1】:
  • 您当前已经注释掉了关闭update 函数的},因此end f 的行实际上并未结束f()。在当前状态下,您的代码不会执行。 (我注意到其他人编辑了您的代码,之后此评论不再有效;我不知道编辑是否更接近您的实际代码,或者它是否确实掩盖了真正的错误)

    李>
  • 您指的是multiplecallsmultipleCalls。请注意,javascript 区分大小写。

  • 您正在清除multipleCalls,但从未将其设置为null。你打算写multipleCalls = setTimeout(update, 1000) 吗?

  • start,位于f 之外,将无法访问update。在 f() 之外定义 update 及其依赖的函数,或者使其全局可访问,即

    window.update = function() { ... }
    

    然后您可以以setTimeout(window.update, 1000); 的身份访问它

【讨论】:

  • Hedlung 多次调用是我的错误。
【解决方案2】:

您有一个范围界定问题。 update 仅在f 内已知。

您正试图在start 中从外部f 调用它。实现这一点的唯一方法是将function update 暴露在与start 相同的范围内,或者将start 置于与update 相同的范围内。

第一个选项最简单(也是最丑陋的):

function update() {
  //...
}
//  assign it to the global scope (window is the global scope for browsers)
window.update = update;

现在 update 可以从 `starts 获得。

更合适的方法是定义您的处理程序(例如,在 f 的范围内调用 startstop

$(function f() {
  //.. everything there now

  $('.start').on('click', function(e) {
    setTimeout(update, 1000);
  });
});

工作示例

$(function f() {
  var timer;  //  no need to be 'global'
  
  function update() {
     $('.result').text(new Date() + ' GetData();');
  }

  $('.start').on('click', function() {
    //  always clear a timer before setting it
    clearTimeout(timer);
    //  and always set a timer variable, so it can be cancelled
    timer = setTimeout(update, 1000);
  });

  $('.stop').on('click', function() {
    //  cancel the timer
    clearTimeout(timer);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button class=start>start</button>
<button class=stop>stop</button>

<div class=result>..</div>

【讨论】:

  • Rogier,非常感谢您的示例。我有另一种类型的按钮,所以情况有点不同。
  • 那么,这些示例是否有助于您了解实际问题和可能的解决方案?如果没有,请告诉我如何进一步澄清。
【解决方案3】:

你可以试试这个:

window.update = function update() {...} 

然后:

setTimeout(window.update, 1000);

【讨论】:

    猜你喜欢
    • 2018-06-24
    • 1970-01-01
    • 2018-12-03
    • 2016-01-04
    • 1970-01-01
    • 2013-10-11
    • 2020-03-29
    • 1970-01-01
    • 2020-05-19
    相关资源
    最近更新 更多