卡在一段 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)
因为它似乎 currentState
是 btnPress
的属性(或者可能不是 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.off
。 State.off
有一个 btnPress
属性 链接到一个函数。按原样调用 currentState.call(_self)
将 this
属性 设置为 _self
,这是 Light
对象本身。这样,btnPress
函数就像 Light
对象的方法一样。
您的建议没有意义,因为 _self
(Light
对象)没有 btnPress
属性。它有一个 currentState
属性,这是一个 btnPress
属性.
的对象
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)
因为它似乎 currentState
是 btnPress
的属性(或者可能不是 attribute
)?
Does the
this
keyword in constructorLight
points to the same context as thatthis
invar _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.off
。 State.off
有一个 btnPress
属性 链接到一个函数。按原样调用 currentState.call(_self)
将 this
属性 设置为 _self
,这是 Light
对象本身。这样,btnPress
函数就像 Light
对象的方法一样。
您的建议没有意义,因为 _self
(Light
对象)没有 btnPress
属性。它有一个 currentState
属性,这是一个 btnPress
属性.