【问题标题】:JavaScript Scope and setTimeout inside of a "class"“类”中的 JavaScript Scope 和 setTimeout
【发布时间】:2013-01-02 09:52:39
【问题描述】:

我无法解决范围问题。实际上,我正在开发一个 HMI 浏览器前端的项目。它应该可视化来自自动化系统的变量。对于人机界面,要求用户可以在不同的页面之间切换。为了解决一般流程,我创建了一个状态机函数,它协调加载、绘图和与用户的交互。我现在的问题是我使用 setTimeout 来调用 run 函数(这实际上是我的状态机)并且现在使用 var-scope 运行时遇到了问题。

看下面的代码:

function frontend() {

  // Public properties:
  this.soundEnable = true;

  // Private Properties:
  var p1 = 0;
  var p2 = [1,2,3];
  var p3 = {a:1, b:2, c:3};
  var runState = 1;
  var runWait = false:

  // Public Methods

  // stops the state machine until m_continue is called
  this.m_wait = function() {
    runWait = true;
  }

  // continues the state machine
  this.m_continue = function() {
    if (runWait) {
      runWait = false;
      setTimeout(run, 100);
    }
  }

  // Private Methods

  function drawFrame(finish_callback) {
    ...<Drawing of HMI-Objects on the canvas>...
    finish_callback();
  }

  function run() {
    switch (runState) {
    case 1:
      this.m_stop();
      drawFrame(this.m_continue());
    case 2:
      for(i=0; i<p3.length; i++) {
        p2.push(externalObjectCreator(p3[i]));
      }
    }
    if (!runWait) {
      runState++;
      setTimeout(run, 100);
    }
  }

  // Constructor
  ...<code to assign public and private properties>...

  // Finally call the state machine to activate the frontend
  runState = 1;
  run();
}

问题是 run-Function 中的范围。如果从构造函数末尾第一次调用,一切正常。 run 可以访问所有私有属性并对其进行操作。但是当它稍后通过 m_continue 的 setTimeout 或它本身被调用时,我无法访问私有属性。在 firebug 中,我只能看到公共属性和函数,而没有我需要的私有属性。

使用全局变量会有所帮助,但这是不可能的,因为在多显示器解决方案中,我有 2 个单独的画布对象,它们需要显示 HMI 的单独版本 - 在这种情况下,我需要 2 个前端实例并行运行浏览器窗口。

有人知道这个问题的解决方案吗?我的知识已经走到了尽头,完全糊涂了。

【问题讨论】:

    标签: javascript scope settimeout


    【解决方案1】:

    最简单的方法是定义你的范围。许多知名的 javascript 库也使用这种技术。

    this.m_continue = function() {
     that = this;  
     if (runWait) {
          runWait = false;
          setTimeout(that.run, 100);
        }
      }
    

    否则您也可以使用apply 使用范围绑定

    【讨论】:

      【解决方案2】:

      您应该在每个 setTimeout 中绑定 run 函数,因为 run 使用 this

      setTimeout(run.bind(this), 100);
      

      【讨论】:

        猜你喜欢
        • 2021-10-13
        • 2011-08-20
        • 2015-01-24
        • 2011-04-07
        • 2020-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多