当前位置:   article > 正文

js状态栏显示信息怎么设置,javascript 状态机_js 如何控制浏览器状态栏提示信息

js 如何控制浏览器状态栏提示信息

大家好,小编为大家解答js状态栏显示信息怎么设置的问题。很多人还不知道javascript 状态机,现在让我们一起来看看吧!

概念

状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

从电灯说起

需求:

实现一个开关功能的电灯

代码实现:

  1. class Light {
  2. constructor() {
  3. this.state = 'off' // 默认关灯
  4. this.button = null
  5. }
  6. init() {
  7. const button = document.createElement('button')
  8. this.button = document.body.appendChild(button)
  9. this.button.innerHTML = '开关'
  10. this.button.onclick = () => {
  11. this.handleStateChange()
  12. }
  13. }
  14. handleStateChange() {
  15. if(this.state == 'off') {
  16. console.info("开灯")
  17. this.state = 'on'
  18. } else if(this.state == 'on') {
  19. console.info('关灯')
  20. this.state = 'off'
  21. }
  22. }
  23. }
  24. const light = new Light()
  25. light.init()

这个功能暂时告一段落Python中的所有运算符号

但过不久产品经理要求实现这样一种电灯:第一次按下打开弱光,第二次按下打开强光,第三次才是关闭电灯。
你只得更改 handleStateChange 代码为

  1. handleStateChange () {
  2. if (this.state === 'off') {
  3. console.log('弱光')
  4. this.state = 'weakLight'
  5. } else if (this.state === 'weakLight') {
  6. console.log('强光')
  7. this.state = 'strongLight'
  8. } else if (this.state === 'strongLight') {
  9. console.log('关灯')
  10. this.state = 'off'
  11. }
  12. }

功能是实现了,但存在如下问题:

  • 违反单一功能原则,Light 类中应该只负责状态的切换,不应该包含各种状态的逻辑处理
  • 违反开放封闭原则,如果要再加个魔幻灯关类型,还得往 handleStateChange 函数里添加一段逻辑,这样提测的时候,还要求测试人员重头将所有绩效等级测遍。
  • 通过 if else 来做状态切换,如果要实现同时满足多个状态啥的,就会很难维护

优化一(采用状态模式)

封装一般是封装对象的行为,而不是封装对象的状态,但是在状态模式中,关键的就是把每种状态封装成单独的类,跟状态相关的行为都封装在类的内部
首先先拆解出该电灯存在三种状态:OffLightState (关灯)、WeakLightState (弱光)、StrongLightState (强光)。
编写状态类如下:

  1. class OffLightState {
  2. construct (light) {
  3. this.light = light
  4. }
  5. handleStateChange () {
  6. console.log('弱光')
  7. this.light.setState(this.light.weakLightState)
  8. }
  9. }
  10. class WeakLightState {
  11. construct (light) {
  12. this.light = light
  13. }
  14. handleStateChange () {
  15. console.log('强光')
  16. this.light.setState(this.light.strongLightState)
  17. }
  18. }
  19. class StrongLightState {
  20. construct (light) {
  21. this.light = light
  22. }
  23. handleStateChange () {
  24. console.log('关灯')
  25. this.light.setState(this.light.offLightState)
  26. }
  27. }

编写 Light 类:
采用状态对象的形势标识当前的开关状态,而不是之前的字符串( ‘weakLight’、’strongLight‘、‘off’)

  1. class Light {
  2. construct () {
  3. this.offLightState = new OffLightState(this)
  4. this.weakLightState = new WeakLightState(this)
  5. this.strongLightState = new StrongLightState(this)
  6. this.currentState = this.offLightState // 初始化电灯状态
  7. this.button = null
  8. }
  9. init () {
  10. const button = document.createElement('button')
  11. this.button = document.body.appendChild(button)
  12. this.button.innerHTML = '开关'
  13. this.button.onclick = () => {
  14. this.currentState.handleStateChange()
  15. }
  16. }
  17. setState (newState) {
  18. this.currentState = newState
  19. }
  20. }
  21. const light = new Light()
  22. light.init()

有如下优点:

  • 每种状态和它对应的行为之间的关系局部化,这些行为被分散在各个对象的状态类之中,便于阅读和管理。
  • 状态之间的切换逻辑分布在状态类内部,这使得我们无需编写if-else语句来控制状态直接的切换。
  • 当我们需要为 Light 类增加一种新的状态时,只需要增加一个新的状态类,再稍微改变一下现有的代码。

优化二(JavaScript版本策略模式)

非面向对象实现的策略方式,将各个状态定义在一个对象里,通过对象映射的方式,以及 call 语法绑定主体类 Light

  1. const lightState = {
  2. 'offLight': {
  3. handleStateChange:function() {
  4. console.log('弱光')
  5. this.setState(lightState.weakLight)
  6. }
  7. },
  8. 'weakLight': {
  9. handleStateChange:function() {
  10. console.log('强光')
  11. this.setState(lightState.strongLight)
  12. }
  13. },
  14. 'strongLight': {
  15. handleStateChange:function() {
  16. console.log('关灯')
  17. this.setState(lightState.offLight)
  18. }
  19. }
  20. }
  21. class Light {
  22. constructor () {
  23. this.currentState = lightState.offLight // 初始化电灯状态
  24. this.button = null
  25. }
  26. init () {
  27. console.info(this,"this")
  28. const button = document.createElement('button')
  29. this.button = document.body.appendChild(button)
  30. this.button.innerHTML = '开关'
  31. this.button.onclick = () => {
  32. this.currentState.handleStateChange.call(this) // 通过 call 完成委托
  33. }
  34. }
  35. setState (newState) {
  36. this.currentState = newState
  37. }
  38. }
  39. const light = new Light()
  40. light.init()

状态模式使用场景

  • 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
  • 一个操作中含有大量的分支语句,而且这些分支语句依赖于该对象的状态。状态通常为一个或多个枚举常量的表示。

采用 java-state-machine 完成状态配制

比如实现个收藏,与取消收藏功能

  1. import StateMachine from 'java-state-machine'
  2. import $ from 'jquery'
  3. var fsm = new StateMachine({
  4. init: '收藏',
  5. transitions: [
  6. { name: 'doStore', from: '收藏', to: '取消收藏' },
  7. { name: 'deleteStore', from: '取消收藏', to: '收藏' }
  8. ],
  9. methods: {
  10. onDoStore: function () {
  11. console.log('收藏成功')
  12. updateText()
  13. },
  14. onDeleteStore: function () {
  15. console.log('取消收藏成功')
  16. updateText()
  17. }
  18. }
  19. })
  20. const updateText = function () {
  21. $('#btn1').text(fsm.state)
  22. }
  23. $('#btn1').on('click', function () {
  24. if (fsm.is('收藏')) {
  25. fsm.doStore()
  26. } else {
  27. fsm.deleteStore()
  28. }
  29. })
  30. // 初始化
  31. updateText()

采用状态模式实现 promise

promise 的 pending fulfilled rejected 是三个不同的状态,并且每种状态都有相应的行为

  1. import StateMachine from 'java-state-machine'
  2. var fsm = new StateMachine({
  3. init: 'pending',
  4. transitions: [
  5. { name: 'resolve', from: 'pending', to: 'fulfilled' },
  6. { name: 'reject', from: 'pending', to: 'rejected' }
  7. ],
  8. methods: {
  9. onResolve: function (state, data) {
  10. data.successCallBacks.forEach((fn) => fn())
  11. },
  12. onReject: function () {
  13. data.failCallBacks.forEach((fn) => fn())
  14. }
  15. }
  16. })
  17. class MyPromise {
  18. constructor(fn) {
  19. this.successCallBacks = []
  20. this.failCallBacks = []
  21. fn(
  22. () => {
  23. fsm.resolve(this)
  24. },
  25. () => {
  26. fsm.reject(this)
  27. }
  28. )
  29. }
  30. then(successCall, failCall) {
  31. this.successCallBacks.push(successCall)
  32. this.failCallBacks.push(failCall)
  33. }
  34. }
  35. const loadImg = function (src) {
  36. const promise = new MyPromise((resolve, reject) => {
  37. const img = document.createElement('img')
  38. img.onload = function () {
  39. resolve(img)
  40. }
  41. img.onerror = function (err) {
  42. reject(err)
  43. }
  44. img.src = src
  45. })
  46. return promise
  47. }
  48. var src = ' //www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
  49. let result = loadImg(src)
  50. result.then(function (img) {
  51. console.info('ok1')
  52. })
  53. result.then(function (img) {
  54. console.info('ok2')
  55. })

只是实现 promise 功能的一部分,但已足够说明状态模式的使用方式

状态模式与策略模式的比较

相同点:
它们都有一个上下文、一些策略或者状态类,上下文把请 求委托给这些类来执行
不同点:
策略模式:各个策略类之间是平等又平行的,它们之间没有任何关系,所以客户必须熟知这些策略类的作用,以便客户自己可以随时主动切换算法。
状态模式:状态和状态对应的行为早已被封装好,状态之间的切换也早就被规定,“改变行为”这件事发生在状态模式的内部,对于客户来说,不需要了解这些细节。比如电灯的开与关,是由程序切换的,不用用户传入状态值。

参考链接

JavaScript设计模式与开发实践

结语

你的点赞是对我最大的肯定,如果觉得有帮助,请留下你的赞赏,谢谢!!!

文章知识点与官方知识档案匹配,可进一步学习相关知识
Python入门技能树首页概览424513 人正在系统学习中
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/696592
推荐阅读
相关标签
  

闽ICP备14008679号