JavaScript实现接口的三种经典方式

 

 

  1 /*
  2 接口:提供一种说明一个对象应该有哪些方法的手段
  3 js中有三种方式实现接口:
  4     1 注释描述接口
  5     2 属性检测接口
  6     3 鸭式辨型接口
  7 */
  8     
  9 /*
 10 1 注释描述接口: 不推荐
 11     优点: 利用注解,给出参考
 12     缺点:纯文档约束,是一个假接口,
 13         程序不能检查实现接口对象是否实现所有接口方法
 14 */
 15 
 16 /**
 17  * interface Composite{
 18  *         function a();
 19  *         function b();
 20  * }
 21  */
 22 // CompositeImpl implements Composite
 23 var CompositeImpl = function(){
 24     //业务逻辑
 25 };
 26 CompositeImpl.prototype.a = function(){
 27     //业务逻辑
 28 };
 29 CompositeImpl.prototype.b = function(){
 30     //业务逻辑
 31 };
 32     
 33     
 34     
 35     
 36     
 37     
 38     
 39 /*
 40 2 属性检测接口:
 41     优点:能够检测实现哪些接口
 42     缺点:没有完全脱离文档,
 43         不能检测是否实现每个接口里的所有方法
 44 */
 45 /**
 46  * interface Composite{
 47  *         function a();
 48  * }
 49  * 
 50  * interface FormItem(){
 51  *         function b();
 52  * }
 53  */
 54 // CompositeImpl implements Composite,FormItem
 55 var interfacesImpl = function(){
 56     //在实现类内部用一个数组保存要实现的方法名
 57     //通常这个属性名是团队中规定好的
 58     this.implementsInterfaces = ["Composite","FormItem"];
 59 };
 60 CompositeImpl.prototype.a = function(){
 61     //业务逻辑
 62 };
 63 CompositeImpl.prototype.b = function(){
 64     //业务逻辑
 65 };
 66 
 67 //专门为这个实现对象写一个检测函数,传入实例对象,用于检查实力对象是否实现了所有接口
 68 function checkImplements(obj){
 69     //调用检查方法 obj是否实现两个接口,如果没有都实现则抛出异常
 70     if(!isImplements(obj,"Composite","FormItem")){
 71         throw new Error("接口没有全部实现!");
 72     }
 73     //接收一个参数obj是要检查的对象
 74     function isImplements(obj){
 75         //arguments对象能够获取实际传入函数的所有参数的数组
 76         //传入的第0个参数是要检查的对象,所以从1开始检查
 77         for(var i = 1; i < arguments.length ; i++){
 78             //接收接口中每个接口的名字
 79             var interfaceName = arguments[i];
 80             //一个标记,是否实现这个接口,默认没有
 81             var foundFlag = false;
 82             //循环查询传入实例对象的实现接口数组 以检查是否全部实现
 83             for(var j = 0 ;j <obj.implementsInterfaces.length;j++){
 84                 //如果 实现了这个接口 就修改标记跳出循环
 85                 if(obj.implementsInterfaces[j]==interfaceName){
 86                     foundFlag = true;
 87                     break;
 88                 }
 89             }
 90             //如果遍历实现接口数组之后没找到 就返回false
 91             if(!foundFlag){
 92                 return false;
 93             }
 94         }
 95         //如果都找到了 返回true
 96         return true;
 97     }
 98 }
 99 
100 //使用实力对象并检测
101 var o = new interfacesImpl();
102 checkImplements(o);    //不会抛出异常 因为正确实现了两个接口
103 //如果在写interfacesImpl内的implementsInterfaces列表的时候少写了,那么就会在检查函数中抛出异常
104 
105 
106 
107 
108 /*
109 3 鸭式辨型法:(目前开发中使用的方式)
110     实现思想: 
111 
112 */
113 
114 //1 接口类 Class Interface
115 /**
116  * 接口类需要的参数:
117  * 1 接口的名字
118  * 2 要实现方法名称的数组
119  */
120 var Interface = function( name , methods ){
121     //判断参数个数
122     if(arguments.length!=2){
123         throw new Error("接口构造器参数必须是两个!");
124     }
125     this.name = name;
126     this.methods = [];
127     for(var i = 0;i<methods.length;i++){
128         if( typeof methods[i] !== "string" ){
129             throw new Error("接口实现的函数名称必须是字符串!");
130         }
131         this.methods.push(methods[i]);    
132     }
133     
134 };
135 //2 准备工作:
136 // 2.1 实例化接口对象    传入接口名 和 要实现的方法数组
137 var CompositeInterface = new Interface("CompositeInterface",["add","remove"]);
138 var FormItemInterface = new Interface("FormItemInterface",["update","select"]);
139 
140 //  2.2 实现接口的类
141 //CompositeImpl implementes CompositeInterface ,FormItemInterface
142 var CompositeImpl = function(){
143     
144 };
145 //  2.3 实现接口的方法
146 CompositeImpl.prototype.add = function(obj){
147     alert("add...");
148 };
149 CompositeImpl.prototype.remove = function(obj){
150     alert("remove...");
151 };
152 CompositeImpl.prototype.select = function(obj){
153     alert("select...");
154 };
155 //在这里少实现一个方法 下面检测是否全部实现了接口方法
156 // CompositeImpl.prototype.update = function(obj){
157     // alert("update...");
158 // };
159 // 实例化   实现接口的对象
160 var c = new CompositeImpl();
161 
162 //3 检验接口里的方法是否全部实现
163 // 如果检验通过 继续执行;如果不通过抛出异常;
164 Interface.ensureImplements = function(obj){
165     // 如果接收到参数小于2 说明 传参出错了,只传入一个参数,,没有传入实现的接口
166     if(arguments.length<2){
167         throw new Error("接口检查方法的参数必须多余两个!");
168     }
169     //获得要见测的接口实现对象之后的参数 各个接口
170     for(var i = 1,len = arguments.length;i<len;i++){
171         var instanceInterface = arguments[i];    //获取当前这个接口
172         //判断接收到的是不是接口的对象  如果不是 抛出异常
173         if( instanceInterface.constructor !== Interface){
174             throw new Error("接口检测函数必须传入接口对象!");
175         }
176         //检查实例化接口的对象是不是实现了接口里的所有方法
177         // 当前接口对象里的每一个方法
178         for(var j = 0 ; j<instanceInterface.methods.length;j++){
179             var methodName = instanceInterface.methods[j]; //接收到了字符串的方法名
180             //如果obj里面没有有methodName这个方法 或者有这个属性但是不是函数 就抛出异常
181             if(!obj[methodName] || typeof obj[methodName] !== "function"){
182                 throw new Error("接口方法"+ methodName +"没有实现!");
183             }
184         }
185     }
186     
187     
188 };
189 //传入要检查的类,和他要实现的所有接口对象
190 Interface.ensureImplements(c ,CompositeInterface ,FormItemInterface );
191 c.add();
192     

 

转载于:https://www.cnblogs.com/Lin-Yi/p/7455521.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

eclipse启动tomcat不能正常访问问题

问题&#xff1a; 1、eclipse中配置好tomcat服务器后&#xff0c;启动tomcat查看控制台信息显示启动成功&#xff0c; 但访问tomcat首页报404异常 2、而从tomcat/bin目录中启动后&#xff0c;就能够正常访问首页&#xff0c;由此分析应该是eclipse配置错误 解决方案&#xff1a…

AD域

将网络中的计算机逻辑上组织到一起&#xff0c;将器视为一个整体进行集中管理&#xff0c;这种区别于工作组的逻辑环境叫做Windows域。windows管理模式有两种&#xff1a;工作组和与环境。活动目录的相关概念(1)域和域控制器(2)名称空间(3)对象和属性(4)容器(5)组策略活动目录的…

人工智能领域2023年12月15日-12月24日大事件

时代在高速的发展&#xff0c;本文让你快速了解人工智能领域12月15日至12月24日大事件。 文章目录 1 全球AI芯片市场规模预计突破千亿美元2 AI在金融领域的应用取得重大突破3 AI在医疗领域取得重大突破4 全球首个AI教育平台正式发布5 全球首个AI驾驶执照颁发6 AI助力农业增产增…

pycharm如何汉化

https://blog.csdn.net/jia666666/article/details/81777017 我们将汉化包里面的resource_zh.jar文件放入pycharm安装目录lib文件下面即可。

Python学习笔记19(算法)

1.二分查找 只能用二分查找查找有序列表 def bin_search(data,val): #data为被查找的列表&#xff0c;val是要查找的值low 0high len(data) - 1while low < high:mid (lowhigh)//2if data[mid] val:return mid #找到了&#xff0c;返回val所在的索引elif dat…

C#通过接口与线程通信(捕获线程状态)介绍

摘要&#xff1a;本文介绍C#通过接口与线程通信(捕获线程状态)&#xff0c;并提供简单的示例代码供参考。 提示&#xff1a;本文所提到的线程状态变化&#xff0c;并不是指线程启动、暂停、停止&#xff0c;而是说线程内部状态的迁移。随着软件技术不断发展&#xff0c;用户需求…

php 类文件加载 Autoloader

做习惯了编译语言&#xff0c;转到php 使用 php的面向对象开发时候遇见一个挺别扭的问题。在Php中引入对象 后 在调用过程中还需要将对象所在的php文件 require 到当前php文件 目前代码结构 index.php <?phpuse model\BookModel;include_once __DIR__./autoloader.php; Aut…

【MSP430G2553】图形化开发笔记(4) Timer_A 定时器

目录概述Timer_A 模块16 位主定时器连续计数模式增计数模式增减计数模式主定时器的一般设置捕获/比较模块 CCRx捕获模块比较模块小结Grace中配置Timer_ATimer0_A3 - Overview介绍用例&#xff1a;定时器的启动/停止用例&#xff1a;使用定时器比较模式产生周期性间隔用例&#…

flask学习笔记--蓝图

https://blog.csdn.net/m0_37519490/article/details/80627601 初学者建议看 https://www.cnblogs.com/jackadam/p/8684148.html

前端UI框架《Angulr》入门

Angulr 项目的名称为 Angulr&#xff0c;对&#xff01;没错&#xff01;就是少个 a&#xff0c;少个 a 就是它正确的拼写。 是一个以 Bootstrap 和 AngularJS 为基础&#xff0c;并使用了大量前端开源组件合成的一个前端UI框架&#xff0c;是非常棒的UI框架。 今天就来和大家讲…

比赛一买香蕉问题---解题报告

买香蕉问题 题目大意&#xff1a; 士兵想买W个香蕉。买第一个香蕉K美元&#xff0c;第二个2K美元&#xff0c;以此类推&#xff0c;第i 个香蕉iK美元。 现在该士兵有n美元&#xff0c;而他想买W个香蕉&#xff0c;他需要向他的朋友借多少美元&#xff1f; 要求&#xff1a; 输入…

Flask使用Flask-SQLAlchemy操作MySQL数据库

https://www.jianshu.com/p/6ae0d30a5539 前言&#xff1a; Flask-SQLAlchemy是一个Flask扩展&#xff0c;简化了在Flask程序中使用SQLAlchemy的操作。SQLAlchemy是一个很强大的关系型数据库框架&#xff0c;支持多种数据库后台。SQLAlchemy提供了高层ORM&#xff0c;也提供了…

会计基础模拟练习一(3)

会计基础模拟练习一&#xff08;3&#xff09; 下周一18号会计从业资格考试就要报名了,本人重点看的是会计基础和会计电算化,做了一下测试题,五十多分,较之前有了一些长进.很多之前重点复习的章节有了明显的提升,像后面的几章没怎么看,出错的概率就大大的提升了. 我觉得这个考试…

[2017-08-31]如何使用ruby同步markdown博文到博客园

这两天折腾了一下用ruby通过MetaWeblog接口把本博客同步到博客园&#xff0c;特此记录。 MetaWeblog MetaWeblog是一个专门关于博客的协议标准&#xff0c;通过xmlrpc&#xff0c;很简单的定义了新增、编辑、删除三个基本接口。 在博客园设置页签的最下方&#xff0c;保存按钮之…

MacOS中Dock栏的设置和使用技巧,新手必看

MacOS中Dock栏的设置和使用技巧&#xff0c;新手必看 Dock栏就是Mac放置常用应用程序和文件夹快捷方式的任务栏&#xff0c;为你访问这个应用和文件提供了非常方便的入口。 作为Mac用户最常使用的区域&#xff0c;要知道如何才能更高效的使用它&#xff0c;从而达到事半功倍的…

ldconfig deferred processing now taking place

在ubuntu下面安装软件&#xff0c;安装结束后&#xff0c;提示&#xff1a;ldconfig deferred processing now taking place 到网上查询了一下&#xff0c;大概意思是说&#xff1a;软件安装完了&#xff0c;是否要重启电脑。转载于:https://www.cnblogs.com/wangkongming/p/…

51Nod 1003 阶乘后面0的数量 | 思维

题意&#xff1a;n的阶乘后面0的个数&#xff0c;如果直接算出阶乘再数0的数量一定会超时的。因为102*5,所以求出5贡献的次数就行。#include "bits/stdc.h" using namespace std; #define LL long long #define INF 0x3f3f3f3f3f #define PI acos(-1) #define N 510 …

史上超详细的flask_sqlalchemy连接mysql数据库

https://www.jianshu.com/p/1ba45bd6c351 PythonFlask安装&#xff1a;https://www.jianshu.com/p/cd1925e90eda Flask路径参数以及请求参数讲解&#xff1a;https://www.jianshu.com/p/54057b4f0437 首先安装pymysql&#xff0c;命令如下&#xff1a;pip install pymysql 安装…

中国移动技术愿景2020+

2019独角兽企业重金招聘Python工程师标准>>> 中国移动技术愿景2020 本文档白皮书是中国移动提出的在2020年及其之后的若干年内对产业各方面技术发展的构想&#xff0c;包括行业发展趋势&#xff0c;面向万物的数字化服务和对技术发展的看法。希望产业各方面能够开展…

jQuery对象与dom对象的转换

jQuery对象与dom对象的转换只有jquery对象才能使用jquery定义的方法。注意dom对象和jquery对象是有区别的&#xff0c;调用方法时要注意操作的是dom对象还是 jquery对象。普通的dom对象一般可以通过$()转换成jquery对象。如&#xff1a;$(document.getElementByIdx_x("msg…