对于类 引擎," 开始"和" 停止"两个public methods
内部调用" ignitionOn "和" ignitionOff "。
在" 开始"被称为private method
设置变量" ignitionIndicator
"到" true
"在engine instance
和" stop
"将其设置为" false
"。
然而,这种情况并没有发生。自从" ignitionIndicator"以来,出现了一些问题。值总是"未定义"。我必须牢记以下几点。
(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
答案 0 :(得分:3)
您需要调用这些方法,以便this
引用一个实例,例如通过Function#call
或Function#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>
附注:函数声明后面没有;
。 ;
是语句终止符,函数声明(例如ignitionOn
和ignitionOff
的声明)不是语句。