资讯专栏INFORMATION COLUMN

javascript之观察者模式

Riddler / 3249人阅读

摘要:观察者模式应用场景场景一当观察的数据对象发生变化时自动调用相应函数。比如的双向绑定场景二每当调用对象里的某个方法时就会调用相应访问逻辑。

观察者模式

应用场景:

场景一: 当观察的数据对象发生变化时, 自动调用相应函数。比如 vue 的双向绑定;
场景二: 每当调用对象里的某个方法时, 就会调用相应"访问"逻辑。比如给测试框架赋能的 spy 函数;

场景一: 双向绑定

Object.defineProperty
使用 Object.defineProperty(obj, props, descriptor) 实现观察者模式, 其也是 vue 双向绑定 的核心, 示例如下(当改变 obj 中的 value 的时候, 自动调用相应相关函数):

</>复制代码

  1. var obj ={
  2. data: {list:[]}
  3. }
  4. Object.defineProperty(obj,"list",{
  5. get(){
  6. return this.data["list"]
  7. },
  8. set(val){
  9. console.log("值被更改了")
  10. this.data["list"] = val
  11. }
  12. })

Proxy
Proxy/Reflect 是 ES6 引入的新特性, 也可以使用其完成观察者模式, 示例如下(效果同上):

</>复制代码

  1. var obj = {
  2. value: 0
  3. }
  4. var proxy = new Proxy(obj,{
  5. set: function(target,key,value,receiver){
  6. console.log("调用响应函数")
  7. Reflect.set(target,key,value,receiver)
  8. }
  9. })
  10. proxy.value = 1

场景二
下面来实现 sinon 框架的 spy 函数:

</>复制代码

  1. const sinon = {
  2. analyze: {},
  3. spy:function(obj,fnName){
  4. const that = this
  5. const oldFn = Object.getOwnPropertyDescriptor(obj,fnName).value
  6. Object.defineProperty(obj,fnName,{
  7. value:function(){
  8. oldFn()
  9. if(that.analyze[fnName]){
  10. that.analyze[fnName].count = ++that.analyze[fnName].count
  11. }else{
  12. that.analyze[fnName] = {}
  13. that.analyze[fnName].count = 1
  14. }
  15. console.log(`${fnName}被调用了${that.analyze[fnName].count}`)
  16. }
  17. })
  18. }
  19. }
  20. const obj = {
  21. someFn: function(){
  22. console.log(`my name is someFn`)
  23. }
  24. }
  25. sinon.spy(obj,"someFn")
  26. obj.someFn()
  27. // my name is someFn
  28. // someFn被调用了一次
  29. obj.someFn()
  30. // my name is someFn
  31. // someFn 被调用了2次
  32. 每当调用对象里的某个方法时, 就会调用相应"访问"逻辑。给测试框架赋能的 spy 函数;
vue 在 3.0 版本上使用 Proxy 重构的原因

首先罗列 Object.defineProperty() 的缺点:

Object.defineProperty() 不会监测到数组引用不变的操作(比如 push/pop 等);

Object.defineProperty() 只能监测到对象的属性的改变, 即如果有深度嵌套的对象则需要再次给之绑定

Object.defineProperty();

关于 Proxy 的优点

可以劫持数组的改变;

defineProperty 是对属性的劫持, Proxy 是对对象的劫持;

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/110035.html

相关文章

  • JavaScript设计模式发布-订阅模式察者模式)-Part1

    摘要:设计模式与开发实践读书笔记。发布订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系。附设计模式之发布订阅模式观察者模式数据结构和算法系列栈队列优先队列循环队列设计模式系列设计模式之策略模式 《JavaScript设计模式与开发实践》读书笔记。 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖它的对象都将得到通知。 例...

    muzhuyu 评论0 收藏0
  • JavaScript设计模式发布-订阅模式察者模式)-Part2

    摘要:设计模式与开发实践读书笔记。看此文章前,建议先看设计模式之发布订阅模式观察者模式在中,已经介绍了什么是发布订阅模式,同时,也实现了发布订阅模式。 《JavaScript设计模式与开发实践》读书笔记。 看此文章前,建议先看JavaScript设计模式之发布-订阅模式(观察者模式)-Part1 在Part1中,已经介绍了什么是发布-订阅模式,同时,也实现了发布-订阅模式。但是,就Part1...

    Charlie_Jade 评论0 收藏0
  • JavaScript设计模式发布-订阅模式察者模式)-Part2

    摘要:设计模式与开发实践读书笔记。看此文章前,建议先看设计模式之发布订阅模式观察者模式在中,已经介绍了什么是发布订阅模式,同时,也实现了发布订阅模式。 《JavaScript设计模式与开发实践》读书笔记。 看此文章前,建议先看JavaScript设计模式之发布-订阅模式(观察者模式)-Part1 在Part1中,已经介绍了什么是发布-订阅模式,同时,也实现了发布-订阅模式。但是,就Part1...

    chemzqm 评论0 收藏0

发表评论

0条评论

Riddler

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<