访问者模式

2020-11-06  本文已影响0人  小宇cool

1. 访问者模式

1.1 定义

访问者模式( visitor),可以在不改变对象的前提向, 定义作用于对象的新操作.

这个模式在面向对象强类型的语言中实现起来还是比较麻烦的, 但是在JavaScript这种弱类型语言来说实现起来非常简单, 因为访问者模式几乎是原生实现的

1.2 作用

  1. 让对象的执行算法随着访问者的改变而改变
  2. 增强代码的可扩展性
  3. 将稳定数据结构和具体的操作进行解耦

1.3 应用场景

 let person = {
     // 给执行上下文this对象添加两个属性
     addAttr(){
         this.sex = '男';
         this.hobby = '打篮球'
     }
 }
 person.addAttr();
let obj = {};
obj.addAttr.call(obj)

对象person拥有addAttr方法, 作用是个对象添加两个属性, 现在我们想给对象obj也添加这两个属性, 但我们不希望obj拥有addAttr方法, 此时我们可以使用call指定一下addAttr执行上下文this文为obj就可以解决,因此我们可以看到原生JavaScript属性访问者模式非常简单,借助call/apply就可以实现

JavaScript里面用很多原生的API都采用访问者模式的操作, 就比如数组相关的操作

我们都知道函数的arguments对象是一个类数组对象,它有length属性,长得很像数组,但他不是一个真正的数组类型,所以它的原型上没有数组原型上许多好用的方法. 但是我们借用访问者模式来调用数组原生的各种好用的api;

  function add(){
      return Array.prototype.reduce.call(arguments,(total,next) =>{
          return total + next
      },0)
  }
console.log(add(1, 2, 3, 4, 5, 6))// 21

通过借用数组原型的reduce方法利用call方法指定对应的context为arguments, 并传入对应的回调函数参数,我们实现了对类数组的每一项累加操作.

我们都知道数组用push方法, 现在我们希望普通对象x也有push方法也能添加数组属性和length

let Visitor = {
      push(obj,value){
          return Array.prototype.push.call(obj,value)
      }
  }
let x  = {};
Visitor.push(x,111);
console.info(x)//{0: 111, length: 1}

上面的代码我们通过定义了Visitor访问者对象,并为其添加了push方法, 内部原理还是借用call方法来改变数组push方法的执行上下文, 实现人普通对象也能调用数组的push方法.

总结: 通过访问者模式我们可以在对象的方法上定义新的操作, 而且不会改变原对象的原有形式,这种模式非常灵活,访问者模式使得我们可以很容易的在对象的方法上定义新操作,客户端只需要对应的访问者对象就能实现不同的操作.

上一篇下一篇

猜你喜欢

热点阅读