2013-01-02 33 views
0

我有麻煩來解決範圍問題。其實我正在研究一個HMI瀏覽器前端的項目。它應該可視化來自自動化系統的變量。對於HMI,需要用戶可以在不同的頁面之間切換。爲了解決一般的流程流程,我創建了一個狀態機函數,負責協調加載,繪圖和與用戶的交互。我現在的問題是我使用setTimeout來調用運行函數(這實際上是我的狀態機),現在在var-scope中遇到麻煩。JavaScript範圍和setTimeout裏的一個「類」

請看下面的代碼:

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(); 
} 

問題是在運行功能範圍。從構造函數結束的第一個調用的情況下,一切都很好。運行可以訪問所有私有屬性並操作它們。但是當它通過m_continue的setTimeout被調用時,或者它本身我不能訪問私有屬性。在螢火蟲中,我只能看到公共屬性和功能,而沒有我需要的私有屬性。

使用全局變量將有所幫助,但這是不可能的,因爲在多監視器解決方案中,我有2個需要顯示HMI分離版本的獨立畫布對象 - 在這種情況下,我需要2個前端並行運行的實例一個瀏覽器窗口。

有誰知道這個問題的解決方案?我在我的知識的最後,完全困惑。

回答

1

最簡單的方法是定義你的範圍。任何許多renound JavaScript庫也使用這種技術。

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

否則,你也可以使用範圍使用apply

0

你應該綁定在每個setTimeout的運行功能結合,因爲運行使用this

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