使用函数更新值,返回不起作用

时间:2014-02-18 22:40:58

标签: javascript closures function-expression

所以我正在使用一个函数来更新我的值,但我不能让它们恢复。我看到值没有得到更新,但有没有办法将它们保存为函数返回的参考。

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然后我应该能够更新该值。

2 个答案:

答案 0 :(得分:1)

modethis.mode 相同。在您的功能中,您分别在modethis.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

在你如何提及事物方面保持一致 不要混用selfthis,除非您 打算 以获得这些副作用...
除非你有非常非常好的理由这样做(比如你构建一个框架/引擎,而不是使用引擎的游戏/模拟的模块/类;即:构建jQuery和使用 jQuery构建之间的区别,然后你应该避免这样做。

如果你想要暴露给外部世界的闭包("私有")状态,你需要的只是一个返回该值的函数,和/或一个设置它的函数。
突然之间,selfthis之间的差异以及什么时候都会消失,只要你与你如何使用它们一致,你就知道{的价值是什么每次 调用 方法时,{1}}都会成为。

注意我没有回复任何东西......
当我使用this时,默认情况下会返回newthis / 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
        }

    }