所以我正在使用一个函数来更新我的值,但我不能让它们恢复。我看到值没有得到更新,但有没有办法将它们保存为函数返回的参考。
function Amphibia(wheelRadius, finsPerPropeller, propellersSpinDirection, mode) {
this.speed = 0;
this.mode = mode;
var amphibiaWheel = new PropulsionUnits.Wheel(wheelRadius);
var amphibiaPropeller = new PropulsionUnits.Propeller(finsPerPropeller, propellersSpinDirection);
this.changeMode = function () {
if (mode == "land") {
mode = "water";
}
else if(mode == "water") {
mode = "land";
}
return {
mode: mode
}
}
this.accelerate = function() {
if(this.mode == "water"){
this.speed += amphibiaPropeller.acceleration;
}
else if(this.mode == "land"){
this.speed += 4*amphibiaWheel.acceleration;
}
}
this.changePropellerSpinDirection = function() {
amphibiaPropeller.changeSpinDirection();
}
return {
speed: this.speed,
mode: this.mode,
changeMode: this.changeMode,
accelerate: this.accelerate,
changePropellerSpinDirection: this.changePropellerSpinDirection
}
}
所以在这里我遇到了更改模式和changeMode函数表达式的问题。其中的模式应该引用this.mode然后我应该能够更新该值。
答案 0 :(得分:1)
mode
和this.mode
不相同。在您的功能中,您分别在mode
和this.mode
上检查/设置值。
只要你在同一个地方,以同样的方式使用其中一个,就可以正常工作。
var Amphibia = function (wheelRadius, finsPerPropeller, propellersSpinDirection, mode) {
var amphibia = this,
MODES = { LAND : "land", WATER : "water" };
amphibia.getMode = function () { return mode; };
amphibia.setMode = function (val) { mode = val; };
amphibia.changeMode = function () {
amphibia.setMode((mode === MODES.LAND) ? MODES.WATER : MODES.LAND);
};
};
var amphibia = new Amphibia("", "", "", "land");
amphibia.getMode(); // "land"
amphibia.changeMode();
amphibia.getMode(); // "water"
mode
现在是100%私有的,并且对该实例而言是唯一的。
如果您不需要它,那么您可以将其附加到this
,如果您愿意的话。
但这是你的问题:
var Amphibia = function () {
var amphibia = this,
amphibiaPropeller = new Propeller( );
// mode, getMode, setMode, etc...
amphibia.accelerate = function () {
if (amphibia.getMode() === "water") {
this.speed += amphibiaPropeller.acceleration;
}
};
};
var amphibia = new Amphibia();
var bob = { speed : 0 };
bob.accelerate = amphibia.accelerate;
bob.accelerate();
// if amphibia.mode === "water", bob.speed += amphibiaPropeller.acceleration
bob.speed; // === amphibiaPropeller.acceleration
setTimeout(amphibia.accelerate, 10); // call amphibia.accelerate in ~10ms
// if amphibia.mode === "water", window.speed += amphibiaPropeller.acceleration
window.speed; // === amphibiaPropeller.acceleration
在你如何提及事物方面保持一致
不要混用self
和this
,除非您 打算 以获得这些副作用...
除非你有非常非常好的理由这样做(比如你构建一个框架/引擎,而不是使用引擎的游戏/模拟的模块/类;即:构建jQuery和使用 jQuery构建之间的区别,然后你应该避免这样做。
如果你想要暴露给外部世界的闭包("私有")状态,你需要的只是一个返回该值的函数,和/或一个设置它的函数。
突然之间,self
和this
之间的差异以及什么时候都会消失,只要你与你如何使用它们一致,你就知道{的价值是什么每次 调用 方法时,{1}}都会成为。
注意我没有回复任何东西......
当我使用this
时,默认情况下会返回new
(this
/ amphibia
)的值。
如果您想使用私人价值,并返回"揭示模块" (这是我通常喜欢的),那么你可以简单地这样做:
self
或许,如果你想让它看起来更像模块/组件......
var Amphibia = function (mode) {
var getMode = function () { return mode; },
setMode = function (val) { mode = val; },
changeMode = function () {
setMode( mode === "water" ? "land" : "water" );
};
return {
getMode : getMode,
setMode : setMode,
changeMode : changeMode
};
};
var amphibia = new Amphibia("water");
// `new` won't do any harm, but you can also not use it,
// without it saving everything to `window`
amphibia.getMode(); // "water"
amphibia.changeMode();
amphibia.getMode(); // "land"
......或者您喜欢的任何其他结构
你根本不需要 return {
mode : { get : getMode, set : setMode, switch : changeMode }
};
var amphibia = Amphibia("land");
amphibia.mode.get(); // "land"
amphibia.mode.switch();
amphibia.mode.get(); // "water"
var bob = { };
bob.switchAmphibiaMode = amphibia.mode.switch;
bob.switchAmphibiaMode();
amphibia.mode.get(); // "land"
setTimeout(amphibia.mode.switch, 10);
setTimeout(function () { console.log(amphibia.mode.get()); }, 20);
// 10ms amphibia.mode.switch();
// 20ms console.log(amphibia.mode.get());
// > "water"
。
但this
在JavaScript中非常非常谨慎,因为每次调用函数时this
的含义都会发生变化,如果有一半代码使用this
一半使用this
,你会受到一些惊喜。
答案 1 :(得分:0)
我自己找到了答案! :)所以基本上这在函数构造函数中指的是Amphibia,这在this.changeMode函数表达式中引用了对象窗口。因此我们可以定义一个变量self = this;在构造函数中,所以我们可以在函数表达式中引用相同的东西,就像在函数中一样。我解释得有点糟糕,但这是我的固定代码;)
function Amphibia(wheelRadius, finsPerPropeller, propellersSpinDirection, mode) {
this.speed = 0;
var self = this;
self.mode = mode;
var amphibiaWheel = new PropulsionUnits.Wheel(wheelRadius);
var amphibiaPropeller = new PropulsionUnits.Propeller(finsPerPropeller, propellersSpinDirection);
this.changeMode = function () {
if (self.mode == "land") {
self.mode = "water";
}
else if(self.mode == "water") {
self.mode = "land";
}
}
this.accelerate = function() {
if(self.mode == "water"){
this.speed += amphibiaPropeller.acceleration;
}
else if(self.mode == "land"){
this.speed += 4*amphibiaWheel.acceleration;
}
}
this.changePropellerSpinDirection = function() {
amphibiaPropeller.changeSpinDirection();
}
return {
speed: this.speed,
mode: this.mode,
changeMode: self.changeMode,
accelerate: this.accelerate,
changePropellerSpinDirection: this.changePropellerSpinDirection
}
}