For the class Engine , " start " and " stop " are two public methods
which internally calls " ignitionOn " and " ignitionOff ". After " start " is called the private method
sets a variable " ignitionIndicator
" to " true
" on the engine instance
and " stop
" sets it to " false
".
However that is not happening. Something is going wrong since the "ignitionIndicator" value is always "undefined". I have to keeping the following in mind.
(i) Visibility of the methods should be as it is.
(ii) I CAN NOT set the variable directly from the public methods
. The variable should be only and only set from within the 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
You'd need to call those methods such that this
refers to an instance, for instance via Function#call
or Function#apply
, eg:
EngineConstructor.prototype.start = function() {
ignitionOn.call(this);
};
Or alternately, just pass the instance as an argument (procedural style):
EngineConstructor.prototype.start = function() {
ignitionOn(this);
};
// ...
function ignitionOn(instance) {
// does other things and sets this to true
instance.ignitionIndicator = true;
}
The pattern you're using in that code is very odd. You have a function, Engine
, which you use as a constructor (via new
) but which isn't a constructor (it returns something other than the instance created by the new
operator), and the object it returns is unrelated to the Engine
function — instead, it's an instance created by EngineConstructor
. Worse, it creates a whole new EngineConstructor
every time you call it. This is hugely inefficient; if you want to recreate all the methods for every instance, you can do so much more simply.
But I'd just revisit the entire structure so that you do get method reuse. If the goal is to have a constructor function which has access to private methods from prototype methods, the revealing module pattern (applied here to a single constructor) is the usual way to do that:
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>
Side note: Function declarations don't have a ;
after them. ;
is a statement terminator, and function declarations (such as those for ignitionOn
and ignitionOff
) are not statements.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.