2015-05-10 45 views
0

物業對於引擎, 「開始」 和 「停止」 是兩個public methods其內部稱之爲 「ignitionOn」 和 「ignitionOff」。 後「開始」被稱爲private method設置在engine instance變量「ignitionIndicator」到「true」和「stop」設置爲「false」。的JavaScript:調用私有方法的類對象

但是,這沒有發生。由於「點火指示」值總是「未定義」,所以出現了問題。我必須牢記以下幾點。 (i)方法的可見性應保持原樣。 (ii)我不能直接從public methods設置變量。變量應該只能從private method內設置。

function Engine() { 
    function EngineConstructor() { }; 

    // publicly accessible methods 
    EngineConstructor.prototype.start = function() { 
    ignitionOn(); 
    }; 

    EngineConstructor.prototype.stop = function() { 
    ignitionOff(); 
    }; 

    // private methods 
    function ignitionOn() { 
    // does other things and sets this to true 
    this.ignitionIndicator = true; 
    }; 

    function ignitionOff() { 
    // does other things and sets this to false 
    this.ignitionIndicator = false; 
    }; 

    return new EngineConstructor(); 
}; 
var e = new Engine(); 
e.start(); 
e.ignitionIndicator // undefined, should have been true 
e.stop(); 
e.ignitionIndicator // undefined, should have been false 

回答

3

你需要調用這些方法使得this通過Function#callFunction#apply,指的是一個實例,例如如:

EngineConstructor.prototype.start = function() { 
    ignitionOn.call(this); 
}; 

或者交替,你只需要把這個實例作爲論據(程序風格):

EngineConstructor.prototype.start = function() { 
    ignitionOn(this); 
}; 

// ... 

function ignitionOn(instance) { 
    // does other things and sets this to true 
    instance.ignitionIndicator = true; 
} 

模式你」在代碼中使用非常奇怪。你有一個函數,Engine,你用作構造函數(通過new),但其中不是的構造函數(它返回的東西不是由new運算符創建的實例),它返回的對象與Engine函數  —相反,它是由EngineConstructor創建的實例。更糟糕的是,每當你打電話時它會創建一個全新的EngineConstructor。這是非常低效的;如果你想爲每個實例重新創建所有的方法,你可以簡單得多。

但我只是重新審視整個結構,以便您獲得方法重用。如果目標是有它可以訪問從原型方法私有方法構造函數,透露出模塊模式(這裏應用於單個構造函數)是通常的方式做到這一點:

var Engine = function() { 
 
    // The constructor 
 
    function Engine() { 
 
    } 
 

 
    // Publicly accessible methods 
 
    Engine.prototype.start = function() { 
 
     ignitionOn.call(this); 
 
    }; 
 

 
    Engine.prototype.stop = function() { 
 
     ignitionOff.call(this); 
 
    }; 
 

 
    // Private methods 
 
    function ignitionOn() { 
 
     // does other things and sets this to true 
 
     this.ignitionIndicator = true; 
 
    } 
 

 
    function ignitionOff() { 
 
     // does other things and sets this to false 
 
     this.ignitionIndicator = false; 
 
    } 
 

 
    return Engine; 
 
}(); 
 
var e = new Engine(); 
 
e.start(); 
 
snippet.log(e.ignitionIndicator); 
 
e.stop(); 
 
snippet.log(e.ignitionIndicator);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


附註:函數聲明後面沒有;;是語句終止符,函數聲明(例如ignitionOnignitionOff)不是語句。

+1

謝謝@Crowder +1對於很好的解釋! – Tyshawn