卡在一段 JavaScript 有限状态机代码中

Get stuck in a piece of JavaScript Finite State Machine code

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、构造函数Light中的this关键字是否指向与var _self = this;中的this相同的上下文?

2、

时会发生什么
this.lightSwitch.onclick = function() {
            _self.currentState.btnPress.call(_self);
        };

正在执行,此时_self的valve是哪个context?为什么不 self.btnPress.currentState.call(_self) 因为它似乎 currentStatebtnPress 的属性(或者可能不是 attribute)?

Does the this keyword in constructor Light points to the same context as that this in var _self = this; ?

对于常见用法,是的。与许多其他语言不同,Javascript 中的 this 非常动态。但是当你像这样(或使用 ES2015 class 语法)进行 OO 时,this 会按预期工作得很好。之所以引入_self是因为在这个函数内部:

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

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

Why not self.btnPress.currentState.call(_self) because it's seems currentState is an attribute of btnPress(or maybe not "attribute")?

启动时,在构造函数中,currentState 设置为 State.offState.off 有一个 btnPress 属性 链接到一个函数。按原样调用 currentState.call(_self)this 属性 设置为 _self,这是 Light 对象本身。这样,btnPress 函数就像 Light 对象的方法一样。

您的建议没有意义,因为 _selfLight 对象)没有 btnPress 属性。它有一个 currentState 属性,这是一个 btnPress 属性.

的对象