结构性:代理模式
代理模式:在某些情况下,出于某种限制,一个对象不能直接访问另一个对象,需求通过第三者(代理)牵线搭桥从而达到访问的目的。
在ES6中,提供专门以代理角色出现的代理器 --- Proxy。
假设一个场景,有一个介绍所,我们用代理模式模拟一下。
1 /** 2 * 代理模式 保护代理 3 * @param {obj} 目标对象 4 * @param {handler} 对象,定义代理行为,当我们通过proxy访问目标时,handler会进行拦截,handler就是第三方 5 */ 6 const proxy = new Proxy(obj, handler); 7 8 // 女生信息 9 const girl = { 10 name: "西施", 11 about: "我是西施", 12 age: "18", 13 career: "teacher", 14 avatar: "头像", 15 phone: "12455", 16 presents: [], // 礼物数组 17 bottomValue: 50, // 拒收50块以下的礼物 18 lastPresent: present, // 记录最近一次收到的礼物 19 }; 20 // 信息可以分为 普通信息和私密信息 21 const baseInfo = ["age", "name"]; 22 const privateFInfo = ["avatar", "phone"]; 23 24 // 规定礼物的数据结构由type和value组成 25 const present = { 26 type: "巧克力", 27 value: 60, 28 }; 29 30 //男生信息 31 const user = { 32 // 省略 基础信息同上 33 isValidated: true, // 是否实名认证 34 isVIP: false, 35 }; 36 37 // 介绍所 38 const lovers = new Proxy(girl, { 39 get: function (girl, key) { 40 if (baseInfo.indexOf(key) !== -1 && !user.isValidated) { 41 alert("您还没有完成验证哦"); 42 return; 43 } 44 // 此处我们认为只有验证过的用户才可以购买VIP 45 if (user.isValidated && privateInfo.indexOf(key) && !user.isVIP) { 46 alert("只有VIP才可以查看该信息哦"); 47 return; 48 } 49 }, 50 set: function (girl, key, val) { 51 // 给 lastPresent 字段赋值 52 if (key === "lastPresent") { 53 if (val.value < girl.bottomValue) { 54 alert("sorry,您的礼物被拒收了"); 55 return; 56 } 57 // 如果没有拒收,则赋值成功,同时并入presents数组 58 girl.lastPresent = val; 59 girl.presents = [...girl.presents, val]; 60 } 61 }, 62 });
这是代理模式中的 保护代理。所谓的保护代理,就是在访问层做限制,在 getter 和 setter 函数中进行来拦截验证。