- 下面的状态机选择通过Function.prototype.call方法直接把请求委托给某个字面量对象来执行。
var light = function () { this.currstate = FSM.off; this.button = null; }; light.prototype.init = function () { var button = document.createElement('button'); self = this; button.innerHTML = '已关灯'; this.button = document.body.appendChild(button); this.button.onclick = function () { self.currstate.buttonWasPressed.call(self); }; }; var FSM = { off: { buttonWasPressed: function () { console.log('关灯'); this.button.innerHTML = '下一次按我是开灯'; this.currstate = FSM.on; } }, on: { buttonWasPressed: function () { console.log('开灯'); this.button.innerHTML = '下一次按我是关灯'; this.currstate = FSM.off; } } }; var light = new light(); light.init();
- 下面利用delegate函数来重写一遍这个状态机
- 这是面向对象和闭包互换的一个例子。前者将变量保存为对象的属性,后者将变量封闭在闭包形成的环境中:
var delegate = function (client, delegation) { return { buttonWasPressed: function () { return delegation.buttonWasPressed.apply(client, arguments); } }; }; var light = function () { this.offstate = delegate(this, FSM.off); this.onstate = delegate(this, FSM.on); this.currstate = FSM.off; this.button = null; }; light.prototype.init = function () { var button = document.createElement('button'); self = this; button.innerHTML = '已关灯'; this.button = document.body.appendChild(button); this.button.onclick = function () { self.currstate.buttonWasPressed.call(self); }; }; var FSM = { off: { buttonWasPressed: function () { console.log('关灯'); this.button.innerHTML = '下一次按我是开灯'; this.currstate = this.onstate; } }, on: { buttonWasPressed: function () { console.log('开灯'); this.button.innerHTML = '下一次按我是关灯'; this.currstate = this.offstate; } } }; var light = new light(); light.init();
Github上有另外一种方式: