前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript设计模式-代理模式

javascript设计模式-代理模式

作者头像
FE情报局
发布2022-12-05 10:24:22
2830
发布2022-12-05 10:24:22
举报
文章被收录于专栏:FE情报局FE情报局

代理模式在javascript中可以使用Proxy对象,可以更好的去控制一些对象的交互,既然谈到了Proxy,我们先简单了解一下Proxy到底是干什么的

Proxy

Proxy是用来创建一个对象的代理,实现对对象的拦截。比如对象属性的查找、赋值、枚举、函数调用等操作。语法如下

代码语言:javascript
复制
const p = new Proxy(target, handler)
// target 要代理的目标对象
// handler 对象,对象中定义了对target操作时要执行的一些操作

基础使用事例

代码语言:javascript
复制
const handler = {
  get: function(obj, prop) {
    return prop in obj ? obj[prop] : 'FE情报局'
  }
}
const target = {}
const p = new Proxy(target, handler)
p.a = 1
p.b = undefined

console.log(p.a, p.b) // 1, undefined
console.log('c' in p, p.c) // false, FE情报局

原来的target上也有对应的属性a和b,但是要注意,从 target取值的时候并没有走代理,也就是target.c为undefined,target.a等于1 这样我们可以通过代理来对对象取值进行区分,比如对于一些不存在的属性,在取值的时候返回null

代理模式

其实Proxy就是一个代理模式,代理的是一个目标对象,上面的例子也表明它可以将对象的变化做一层代理,任何操作都需要经过此代理做一些额外的操作 你可以将其想象成我们的抓包工具,网络请求进来或者发出都要经过抓包,对其进行一些修改或者处理再给到服务器或者客户端,这种也被称为代理模式

例子

这种模式在我们的项目中具体有什么作用呢?上面我们提到了,可以将不存在的属性设置为null

代码语言:javascript
复制
const handler = {
  get: function(obj, prop) {
    return prop in obj ? obj[prop] : null
  }
}
const target = {}
const p = new Proxy(target, handler)

// p.a => null

数据验证

代理也能够帮我们进行数据验证,能够让目标对象中的数据保持纯正,不会有一些意外的情况

代码语言:javascript
复制
const handler = {
  set: function(obj, prop, value) {
    if(prop === 'age' && value > 0 && value < 100){
      obj['age'] = value
      return true
    }else{
      throw new Error('age的值不符合要求,无法修改')
    }
  }
}
const target = {
  age: 10
}
const p = new Proxy(target, handler)

// p.a => null

断点调试

针对一些有问题的数据,你可以进行一些断点或者log的操作,来看何时何地将什么内容设置为错误的数据

代码语言:javascript
复制
const handler = {
  set: function(obj, prop, value) {
    console.log(`set ${prop} from ${obj[prop]} to ${value}`);
    obj[prop] = value;
    return true
  }
}
const target = {}
const p = new Proxy(target, handler)

p.a = 1
p.a = 2

// set a from undefined to 1
// set a from 1 to 2

格式化数据

代码语言:javascript
复制
const handler = {
  set: function(obj, prop, value) {
    obj[prop] = Number(value);
    return true
  }
}
const target = {}
const p = new Proxy(target, handler)

p.age = '10'

// p.age => 10

扩展对象方法

target可以是任何一个对象,包括数组,所以我们可以通过属性查找数组中的内容

代码语言:javascript
复制
const handler = {
  get: function(obj, prop, value) {
    if(prop in obj){
      return obj[prop]
    }
    let result = null
    for(let item of obj){
      if(item.value === prop){
        result = item
      }
    }
    if(result){
      return result
    }
    return undefined
  }
}
const target = [
  {
    label: '苹果',
    value: 'apple'
  },
  {
    label: '香蕉',
    value: 'banana'
  }
]
const p = new Proxy(target, handler)

// p.length => 2
// p.apple => {label: '苹果', value: 'apple'}
// p[0] => {label: '苹果', value: 'apple'}

总结

代理确实能够方便我们一些操作,并且制定一些通用的handler能够解决我们很多的问题,但是任何东西都要有一个适度,过度使用代理的方式很容易对应用的性能造成一定的影响,所以对于一些关键的代码最好不要使用代理 代理还有一点就是在你排查问题的时候可能会有些困难,比如设置的某一个值不符合你的预期,或者使用的某一个值也不符合你的预期,但是你却不知道你在哪里改了它

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FE情报局 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Proxy
  • 代理模式
  • 例子
    • 数据验证
      • 断点调试
        • 格式化数据
          • 扩展对象方法
          • 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档