用代理模式开一家婚姻介绍所吧
这样看来,开婚介所确实是个发家致富的好路子。既然暴富的机会就在眼前,那么事不宜迟,我们接下来就一起用 JavaScript 来实现一个小型婚介所。
前置知识: ES6中的Proxy
在 ES6 中,提供了专门以代理角色出现的代理器 —— Proxy。它的基本用法如下:
const proxy = new Proxy(obj, handler)
第一个参数是我们的目标对象,也就是上文中的“未知妹子”。handler 也是一个对象,用来定义代理的行为,相当于上文中的“婚介所”。当我们通过 proxy 去访问目标对象的时候,handler会对我们的行为作一层拦截,我们的每次访问都需要经过 handler 这个第三方。
“婚介所”的实现
未知妹子的个人信息,刚问了下我们已经注册了 VIP 的同事哥,大致如下:
// 未知妹子const girl = {// 姓名name: '小美',// 自我介绍aboutMe: '...'(大家自行脑补吧)// 年龄age: 24,// 职业career: 'teacher',// 假头像fakeAvatar: 'xxxx'(新垣结衣的图片地址)// 真实头像avatar: 'xxxx'(自己的照片地址),// 手机号phone: 123456,}
婚介所收到了小美的信息,开始营业。大家想,这个姓名、自我介绍、假头像,这些信息大差不差,曝光一下没问题。但是人家妹子的年龄、职业、真实头像、手机号码,是不是属于非常私密的信息了?要想 get 这些信息,平台要考验一下你的诚意了 —— 首先,你是不是已经通过了实名审核?如果通过实名审核,那么你可以查看一些相对私密的信息(年龄、职业)。然后,你是不是 VIP ?只有 VIP 可以查看真实照片和联系方式。满足了这两个判定条件,你才可以顺利访问到别人的全部私人信息,不然,就劝退你提醒你去完成认证和VIP购买再来。
// 普通私密信息const baseInfo = ['age', 'career']// 最私密信息const privateInfo = ['avatar', 'phone']// 用户(同事A)对象实例const user = {...(一些必要的个人信息)isValidated: true,isVIP: false,}// 掘金婚介所登场了const JuejinLovers = new Proxy(girl, {get: function(girl, key) {if(baseInfo.indexOf(key)!==-1 && !user.isValidated) {alert('您还没有完成验证哦')return}//...(此处省略其它有的没的各种校验逻辑)// 此处我们认为只有验证过的用户才可以购买VIPif(user.isValidated && privateInfo.indexOf(key) && !user.isVIP) {alert('只有VIP才可以查看该信息哦')return}}})
以上主要是 getter 层面的拦截。假设我们还允许会员间互送礼物,每个会员可以告知婚介所自己愿意接受的礼物的价格下限,我们还可以作 setter 层面的拦截。:
// 规定礼物的数据结构由type和value组成const present = {type: '巧克力',value: 60,}// 为用户增开presents字段存储礼物const girl = {// 姓名name: '小美',// 自我介绍aboutMe: '...'(大家自行脑补吧)// 年龄age: 24,// 职业career: 'teacher',// 假头像fakeAvatar: 'xxxx'(新垣结衣的图片地址)// 真实头像avatar: 'xxxx'(自己的照片地址),// 手机号phone: 123456,// 礼物数组presents: [],// 拒收50块以下的礼物bottomValue: 50,// 记录最近一次收到的礼物lastPresent: present,}// 掘金婚介所推出了小礼物功能const JuejinLovers = new Proxy(girl, {get: function(girl, key) {if(baseInfo.indexOf(key)!==-1 && !user.isValidated) {alert('您还没有完成验证哦')return}//...(此处省略其它有的没的各种校验逻辑)// 此处我们认为只有验证过的用户才可以购买VIPif(user.isValidated && privateInfo.indexOf(key)!==-1 && !user.isVIP) {alert('只有VIP才可以查看该信息哦')return}}set: function(girl, key, val) {// 最近一次送来的礼物会尝试赋值给lastPresent字段if(key === 'lastPresent') {if(val.value < girl.bottomValue) {alert('sorry,您的礼物被拒收了')return}// 如果没有拒收,则赋值成功,同时并入presents数组girl.lastPresent = valgirl.presents = [...girl.presents, val]}}})
