var c = console,d = document;
window.onload = function(){
    var Light = function() {
        this.currentState = State.off;
        this.lightSwitch = null;
    };

    Light.prototype.run = function() {
        var _self = this;
        var lightSwitch = d.createElement('button');
        var cvs = d.createElement('canvas');
        cvs.width = '200';
        cvs.height = '200';
        cvs.style.backgroundColor = 'lightblue';
        cvs.style.borderRadius = '50%';
        cvs.style.display = 'block';
        lightSwitch.innerHTML = 'turn on';
        this.lightSwitch = d.body.appendChild(lightSwitch);
        this.cvs = d.body.appendChild(cvs);
        this.lightSwitch.onclick = function() {
            _self.currentState.btnPress.call(_self);
        };
    };

    var State = {
        off: {
            btnPress: function() {
                this.lightSwitch.innerHTML = 'turn off';
                this.cvs.style.display = 'none';
                this.currentState = State.on;
            }
        },
        on: {
            btnPress: function() {
                this.lightSwitch.innerHTML = 'turn on';
                this.cvs.style.display = 'block';
                this.currentState = State.off;
            }
        }
    };
    var light = new Light();
    light.run();
};


我在上面的这段代码中正在学习FSM模式,现在我陷入了状态改变的困境。谁能教我,这是我的问题:

1,构造函数this中的Light关键字是否指向与this中的var _self = this;相同的上下文?

2,什么时候会发生

this.lightSwitch.onclick = function() {
            _self.currentState.btnPress.call(_self);
        };


执行时,_self的阀门在哪个上下文中?为什么不使用self.btnPress.currentState.call(_self),因为似乎currentStatebtnPress的属性(或者可能不是attribute)?

最佳答案

构造函数this中的Light关键字是否指向与this中的var _self = this;相同的上下文?


通常,是的。与许多其他语言不同,Javascript中的this是动态的。但是,当您像这样(或使用ES2015 class语法)进行OO时,this可以正常工作。引入_self的原因是在此函数内部:

this.lightSwitch.onclick = function() {
    _self.currentState.btnPress.call(_self);
};


this将引用DOM元素lightSwitch,而您想引用Light实例。在_self中保存对它的引用是一种常见的技术。


  为什么不使用self.btnPress.currentState.call(_self),因为currentState似乎是btnPress的属性(或者可能不是“ attribute”)?


启动时,在构造函数中,currentState设置为State.offState.off具有链接到函数的btnPress属性。照原样调用currentState.call(_self)会将this属性设置为_self,这是Light对象本身。这样,btnPress函数的作用类似于Light对象的方法。

您的建议没有任何意义,因为_selfLight对象)没有btnPress属性。它具有currentState属性,该属性是具有btnPress属性的对象。

关于javascript - 陷入一段JavaScript有限状态机代码中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48828612/

10-09 17:53
查看更多