>[success] # 适配器模式 ~~~ 1.在了解装饰器前,先了解适配器模式 ~~~ >[info] ## 适配器模式 ~~~ 1.适配器就好比安卓和苹果的充电线,我们的目的是将这两种系统的手机充电,但是需要做的是 将需要两个不同充电线,可以理解电是他们的通用数据,不通用的只是两者线我们需要写一个适配 方法 2.网上最常见的解释:比如连接不同数据库的情况,你需要包装现有的模块接口,从而使之适配数据库 —— 好比你手机使用转接口来适配插座那样; ~~~ >[danger] ##### 案例分析(鸭子进化) <a href='https://www.cnblogs.com/TomXu/archive/2012/04/11/2435452.html'>参考文章汤姆大叔</a> ~~~ 1.汤姆大叔这篇文章涉及的一个知识点,js的继承下面对js继承简单讲解 2.es5中js继承几个要素,第一个使用'apply'等更改指向,第二个'prototype ' 指向原型 ~~~ * 创建一个鸭子的父类,创建了一个继承Duck 类的MallardDuck野鸭类,并重写父类提供的方法 ~~~ // 创建 鸭子类 var Duck = function(){ }; Duck.prototype.fly = function(){ throw new Error('重写') }; Duck.prototype.quack = function(){ throw new Error('重写') }; // 创建一个继承类 var MallardDuck = function () { //更改this 指向 Duck.apply(this); }; // 指定父类 MallardDuck.prototype = new Duck(); // 创建一个对象 var mDuck = new MallardDuck(); // 重写 Duck 中的fly 方法 MallardDuck.prototype.fly = function () { console.log("可以飞翔很长的距离!"); } console.log(mDuck); ~~~ * 这时候创建一个火鸡类父类,让野火鸡类继承火鸡类 ~~~ Turkey.prototype.fly = function(){ throw new Error(" 该方法必须被重写 !"); }; Turkey.prototype.gobble = function(){ throw new Error(" 该方法必须被重写 !"); }; //火鸡 var WildTurkey = function () { Turkey.apply(this); }; WildTurkey.prototype = new Turkey(); //原型是Turkey WildTurkey.prototype.fly = function () { console.log("飞翔的距离貌似有点短!"); }; WildTurkey.prototype.gobble = function () { console.log("咯咯!咯咯!"); }; ~~~ * 现在 想让野火鸡 可以像野鸭子一样叫,也就是让野火鸡有野鸭子的方法最简单的方法 * 直接往野火鸡中加一个野鸭子叫的方法,但假如说不想改变源码的情况下我们制作一个壳子 * 这个壳子包裹住野火鸡,就会有野鸭子的叫声方法(开始适配) ~~~ var TurkeyAdapter = function(oTurkey){ // 要获取具有适配目标对象的东西 Duck.apply(this); // 增加一个对象,这样他可以拥有适配对象的所有方法 this.oTurkey = oTurkey; }; TurkeyAdapter.prototype = new Duck(); TurkeyAdapter.prototype.quack = function(){ // 把野火鸡对象的叫法给了 鸭子,这样调用鸭子叫就会出现野火鸡的声音 this.oTurkey.gobble(); }; ~~~ * 使用 ~~~ var oMallardDuck = new MallardDuck(); var oWildTurkey = new WildTurkey(); // 你是适配器 传递给你需要适配的目标 var oTurkeyAdapter = new TurkeyAdapter(oWildTurkey); //原有的鸭子行为 oMallardDuck.fly(); oMallardDuck.quack(); //原有的火鸡行为 oWildTurkey.fly(); oWildTurkey.gobble(); //适配器火鸡的行为(火鸡调用鸭子的方法名称) oTurkeyAdapter.quack(); ~~~ >[danger] ##### 适配不同对象同一方法名的调用适配器 <a href='https://blog.csdn.net/i10630226/article/details/81432636 '>参考文章 小平果118</a> ~~~ 1.知识点instanceof 判断类型 ~~~ ~~~ const googleMap = { show: function () { console.log('开始渲染谷歌地图'); } }; const baiduMap = { show: function () { console.log('开始渲染百度地图'); } }; const renderMap = function (map) { if (map.show instanceof Function) { map.show(); } }; renderMap(googleMap); // 输出:开始渲染谷歌地图 renderMap(baiduMap); // 输出:开始渲染百度地图 ~~~ >[danger] ##### 针对数据适配 <a href='https://blog.csdn.net/i10630226/article/details/81432636 '>参考文章 小平果118</a> ~~~ 1.像我们将后台数据格式清洗也算一种适配,下面将Echarts折线图后台返回的数据, 适配给前端使用 2.使用map重新定义数组格式 ~~~ * 后台数据 ~~~ [ { "day": "周一", "uv": 6300 }, { "day": "周二", "uv": 7100 }, { "day": "周三", "uv": 4300 }, { "day": "周四", "uv": 3300 }, { "day": "周五", "uv": 8300 }, { "day": "周六", "uv": 9300 }, { "day": "周日", "uv": 11300 } ] ~~~ * js清洗适配数据 ~~~ // 清洗后的目标状态 ["周二", "周二", "周三", "周四", "周五", "周六", "周日"] //x轴的数据 // 清洗后的目标状态[6300. 7100, 4300, 3300, 8300, 9300, 11300] //坐标点的数据 //x轴适配器 function echartXAxisAdapter(res) { return res.map(item => item.day); } //坐标点适配器 function echartDataAdapter(res) { return res.map(item => item.uv); } ~~~