状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变。

    有预感这个模式和react会十分贴合。
    在传统的面向对象的语言中,每种状态都定义了一个状态子类,然后在context中持有这些状态对象的引用,;以便将currState设置为当前的状态。
    在js语言中,状态对象不需要从类中创建出来,且在js中有apply和call这种委托技术,一个对象也不需要持有另一个对象的引用(来调用相关方法)。

    1. var Light=function(){
    2. this.currState=FSM.off
    3. this.button=null
    4. }
    5. Light.prototype.init=function(){
    6. var button=document.createElement('button')
    7. self=this // 为啥要这个self,因为下面onclick用到了light的this而不是button的this
    8. button.innerHTML='已关灯'
    9. this.button=document.appendChild(button)
    10. this.button.onclick=function(){
    11. self.currState.buttonWasPressed.call(self)
    12. }
    13. }
    14. // 然后构建出一个状态对象FSM
    15. var FSM={
    16. off:{
    17. buttonWasPressed:function(){
    18. console.log('关灯')
    19. this.button.innerHTML='开灯'
    20. this.currState=FSM.on
    21. }
    22. },
    23. on:function(){
    24. ...
    25. }
    26. }

    另一种写法,利用delegate函数来编写状态机

    1. var delegate=function(client,delegation){
    2. return {
    3. buttonWasPressed:function(){
    4. return delegation.buttonWasPressed.apply(client,arguments)
    5. }
    6. }
    7. }
    8. var FSM={
    9. // 同上面那个状态机
    10. }
    11. var Light=function(){
    12. this.offState=delegation(this,FMS.off)
    13. this.onState=delegation(this,FMS.on)
    14. this.currState=this.offState
    15. this.button=null
    16. }
    17. // 初始化
    18. Light.prototype.init=function(){
    19. var button=document.createElement('button')
    20. self=this
    21. button.innerHTML='已关灯'
    22. this.button=document.body.appendChild('button')
    23. this.button.onclick=function(){
    24. self.currState.buttonWasPressed()
    25. }
    26. }
    27. var light=new Light()
    28. light.init()