本文共 4991 字,大约阅读时间需要 16 分钟。
接口是提供一种以说明一个对象应该有哪些方法的手段。接口是面向对象javascript程序员的工具箱中最有用的工具之一,那么对于javascript没有定义接口的概念,我们通过模拟高级程序语言的方式来创建javascript中的接口。
通常建立javascript接口有三种方式:
/** * interface Composite { * function add(obj); * function remove(obj); * function uopdate(obj); * } */// CompositeImpl implements Compositevar CompositeImpl = function(){};CompositeImpl.prototype.add = function(obj){ // do something ...}CompositeImpl.prototype.remove = function(obj){ // do something ...} CompositeImpl.prototype.update = function(obj){ // do something ...}var c1 = new CompositeImpl();var c2 = new CompositeImpl();alert(c1.add == c2.add); //true
注解描述的方式,优点是程序员可以有一个参考,缺点是这种还是属于文档的范畴,这种方式太松散,没有检查接口的方法是否完全被实现。
如果这些方法都定义在函数内,那么每次新建对象都会重新创建函数内的方法,对性能会有很大影响,所以通过原型的方式能够很好解决这个问题
/** * interface Composite { * function add(obj); * function remove(obj); * function uopdate(obj); * } * * interface FormItem { * function select(obj); * } * */ // CompositeImpl implements Composite , FormItem var CompositeImpl = function(){ // 显示地在类的内部,定义接受所实现的接口 // 一般来说是一个规范 在类的内部定义一个数组(名字要固定,例如implementsInterfaces ) this.implementsInterfaces = ['Composite' ,'FormItem' ]; }; CompositeImpl.prototype.add = function(obj){ // do something ... alert('add...');};CompositeImpl.prototype.remove = function(obj){ // do something ...}; CompositeImpl.prototype.update = function(obj){ // do something ...}; CompositeImpl.prototype.select = function(obj){ // do something ...}; // 检测CompositeImpl类的对象的function CheckCompositeImpl(instance){ //判断当前对象是否实现了所有的接口 if(!IsImplements(instance,'Composite','FormItem')){ throw new Error('Object does not implement a required interface!'); }}// 公用的具体的检测方法(核心方法) 返回值类型 boolean// 这个方法的主要目地:就是判断 实例对象 有没有实现相关的接口//之所以抽离出来是为了解耦,当判断其他对象时,改方法可以重用,只用定义多个类似上面CheckCompositeImpl的函数function IsImplements(object){ // arguments 对象 获得函数的实际参数 //object就是传入的第一个对象实例参数,下面的循环只用从1开始获取接口列表 for(var i = 1 ; i < arguments.length;i++){ //接受所实现的每一个接口的名字 var interfaceName = arguments[i]; //判断此方法到底成功 还是失败啊 var interfaceFound = false ; for(var j = 0 ; j
这种方式也只能够够判断是否实现了接口,但是无法具体到判断是否实现了接口的某些方法
//鸭式辨型法实现接口(最完美的javascript实现接口方式) //之前所说的注解描述法、属性检测法都有一定的缺陷 //鸭式辨型法的核心是一个类实现了接口里的所有方法,完全面向对象,代码也实现统一和解耦 //一:接口类Class Interface实现了多个接口 /** * 接口类需要2个参数 * 参数1: 接口的名字 (string) * 参数2: 接收方法名称的集合(数组) (array) */ var Interface = function(name, methods) { //判断接口的参数格式 if (arguments.length != 2) { throw new Error('this instance interface constructor arguments must be 2 length!'); } this.name = name; this.methods = []; for (var i = 0, len = methods.length; i < len; i++) { if (typeof methods[i] !== 'string') { throw new Error('the Interface method name is error!'); } this.methods.push(methods[i]); } }; //二:准备工作 //1 实例化接口对象 var CompositeInterface = new Interface('CompositeInterface', ['add', 'remove']); var FormItemInterface = new Interface('FormItemInterface', ['update', 'select']); // CompositeImpl implements CompositeInterface , FormItemInterface // 2 具体的实现类 var CompositeImpl = function() { }; // 3 实现接口的方法implements methods CompositeImpl.prototype.add = function(obj) { alert('add'); // do something ... }; CompositeImpl.prototype.remove = function(obj) { alert('remove'); // do something ... }; CompositeImpl.prototype.update = function(obj) { alert('update'); // do something ... }; CompositeImpl.prototype.select = function(obj) { alert('select'); // do something ... }; // 三:检验接口里的方法 // 如果检验通过 不做任何操作 不通过:浏览器抛出error // (c1, CompositeInterface, FormItemInterface)只关注第一个参数,其他用arguments来获得 Interface.ensureImplements = function(object) { if (arguments.length < 2) { throw new Error('Interface.ensureImplements method constructor arguments must be >= 2!'); } //获得接口实例对象 for (var i = 1, len = arguments.length; i < len; i++) { //判断参数是否是接口类型 var instanceInterface = arguments[i]; if (instanceInterface.constructor !== Interface) { throw new Error('the arguments constructor not be Interface Class'); } //循环接口实例对象里面的每一个方法 for (var j = 0; j < instanceInterface.methods.length; j++) { //用一个临时变量接收每一个方法的名字 var methodName = instanceInterface.methods[j]; if (!object[methodName] || typeof object[methodName] != 'function') { throw new Error("the method name '" + methodName + "' is not found !"); } } } }; var c1 = new CompositeImpl(); Interface.ensureImplements(c1, CompositeInterface, FormItemInterface); c1.add();
转载地址:http://zergi.baihongyu.com/