6JavaScript设计模式--观察者模式\迭代器模式\状态模式

观察者模式

//观察者模式  发布订阅
//主题 保存状态,状态变化 触发
class Subject{
    constructor(){
        this.state = 0
        this.observers = []
    }
    getState(){
        return this.state
    }
    setState(state){
        this.state = state
        this.notifyAllObserves()
    }
    notifyAllObserves(){
        this.observers.forEach(observer => {
            observer.update()
        })
    }
    attact(observer){
        this.observers.push(observer)
    }
}
//观察者
class Observer{
    constructor(name,subject){
        this.name = name
        this.subject = subject
        this.subject.attact(this)
    }
    update(){
        console.log(`${this.name} update,state:${this.subject.getState()}`)
    }
}

let s = new Subject()
let o1 = new Observer('o1',s)
let o2 = new Observer('o2',s) 
let o3 = new Observer('o3',s)
s.setState(1)
s.setState(2)
console.log(s.observers)

迭代器模式

顺序访问一个集合(有序比如数组)

使用者无需知道集合内部结构(封装)

ES6中为Array类(array,map,set,string,nodelist,typedarray,arguments等)增加了一个@@iterator属性。需要通过symbol.iterator来访问。然后不断的调用next()方法。

object 不是有序集合(不能指定下一个,数据是无序的),但是ES6中新增的Map(字典)是无序且有序(有symbol.iterator属性)集合。

// 迭代器模式
class Iterator {
    constructor(container) {
        this.list = container.list
        this.index = 0
    }
    next() {
        if (this.hasNext()) {
            return this.list[this.index++]
        }
        return null
    }
    hasNext() {
        if (this.index >= this.list.length) {
            return false
        }
        return true
    }
}
class Container {
    constructor(list) {
        this.list = list
    }
    //生成迭代器
    getIterator() {
        return new Iterator(this)
    }
}

let arr = [1, 10]
let container = new Container(arr)
let iterator = container.getIterator()
while (iterator.hasNext()) {
    console.log(iterator.next())
}

let arr2 = [2, 20] 
let object1 = {    //object
    name:'lili',
    number:1111
}
let setA = new Set() //集合
setA.add('a')
setA.add('c')
let map1 = new Map() //字典
map1.set('name','jack')
map1.set('num',1234)

function each(data) {
    let iter = data[Symbol.iterator]()
    // console.log(iter.next())
    // console.log(iter.next())
    // console.log(iter.next().value)
    // console.log(iter.next().value)
    // console.log(iter.next())
    // console.log(iter.next())
    let item = {done:false}
    while(!item.done){
        item = iter.next()
        if(!item.done){
            console.log('symbol-iterator',item.value)
        }
    }
}
each(arr2)    //输出value 2 20 200
//each(object1) //错误
each(setA)    //输出 value a b c
each(map1)    //输出 数组 键值对

for(let val of arr2){
    console.log('arr-for-of',val) //输出value 2 20 200
}
for(let val in arr2){
    console.log('arr-for-in',val) // 输出key 0 1 2
}

// TypeError: object1[Symbol.iterator] is not a function
// for(let val of object1){
//     console.log('for-of',val) //错误
// }
for(let val in object1){
    console.log('obj-for-in',val) //输出 name age number
}
// object1.forEach(function(k){  
//     console.log(k)    //错误
// })

for(let val of setA){
    console.log('set-for-of',val) //输出 value a b c
}
for(let val in setA){
    console.log('set-for-in',val) //无输出值
}
setA.forEach(function(v,k){
    console.log(v,k)   //输出 值 值 
})

for(let val of map1){
    console.log('map-for-of',val) //输出 键值对数组
}
for(let val in map1){
    console.log('map-for-in',val) //无输出值
}
map1.forEach(function(v,k){
    console.log(v,k)  //输出 键值对
})
console.log(setA)
console.log(map1)

数组:for..of 输出值 for..in 输出key

object:for..of 错误用法  for..in 输出 属性名称  foreach 错误

set: for..of 输出值 for...in 无输出值  foreach 输出值 没有key 添加参数会重复输出value

map:for..of 输出键值对数组   for...in 无输出值 foreach 输出value和key

可以看出 set \map 的无序 和object的无序是有差别的。object中没有增加了iterator属性,是彻底的无序。而set、map则可以使用迭代器函数,属于Array类。

迭代器方法有:

  • every
  • some
  • forEach
  • map和filter
  • reduce
  • for...of

状态模式

//状态模式
//状态
class State{
    constructor(color){
        this.color = color
    }
    handle(context){
        console.log(`trun to ${this.color} light`)
        context.setState(this)
    }
}
//主体
class Context{
    constructor(){
        this.state = null
    }
    getState(){
        return this.state
    }
    setState(state){
        this.state = state
    }
}

let context = new Context()
let red= new State('red')
let green = new State('green')
let yello = new State('yello')

green.handle(context)
console.log(context.getState())

red.handle(context)
console.log(context.getState())

yello.handle(context)
console.log(context.getState())

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

X01动力装甲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值