Javascript中模拟接口

接口:规定一组规则,但不限定实现这些规则的具体方法,实现这些接口的类必须具有接口所规定的方法。
接口与抽象类的区别:简单而言,类与接口的关系为a live b  can do something,类与抽象类的关系为a is b,so a can do anything b can,另外,抽象类除了虚函数也可以有实现了的方法。

js中模拟根据“鸭式辨型”来模拟接口。

1.鸭式辨型:像鸭子一样走路并呱呱叫的就是鸭子,判断一个类或对象是否实现了一个接口,就检查这个类或对象是否具有接口中规定的所有方法。

2.js对象的反射机制:在程序运行过程中,可以动态检测一个类或对象具有哪些方法和属性,并可以动态执行这些方法,js对象可以用for in 来检测其成员。

for(var pro in obj)
{  //列出obj对象的属性,属性名称pro,属性值obj[pro]
  document.write(pro +":"+ obj[pro] + "<br />");   
}
 
for in 在IE和Firefox中的不同:for in 不会列出对象的默认存在的属性,如果默认属性被重写,在Firefox下会被列出,在IE下则不会。

3.检测对象的继承关系 instanceof
function Person(name,age,sex)
{
this.name=name;
this.age=age;
this.sex=sex;
}
var lily = new Person('lily',25,'female');
if(lily instanceof Person)
{
alert('lily 继承自 Person'); 
}  
 
因为任何js对象都继承自Object对象,因此对于任何js对象obj下式为true:
obj instanceof Object

js对象的易变性:js对象的属性可以被动态修改,因此即使(A instanceof B)为true,也不能保证A具有和B一样的属性,因为A从B继承来的属性可能在使用中被修改或删除掉(在C++中一个实例化的对象是不能被修改的)。

4.接口构造器
/*
Interface函数作为接口的构造器,接收2个参数,第一个为接口名称,第二个为接口要约定的一系列方法
*/
var Interface = function(name, methods)
{
if(arguments.length != 2){
throw new Error("至少需要2个参数");
}

this.name = name;
this.methods = [];

for(var i = 0, len = methods.length; i < len; i++) 
{
if(typeof methods[i] !== 'string'){
throw new Error("请使用字符串来描述接口所约定的方法.");
}
this.methods.push(methods[i]);        
}   
};

/*
 
用于检查一个对象是否实现了接口,该方法接受多个object类型参数,第一个为需要检查的对象,其余参数为该对象期望实现的接口
这是一个静态方法, 这个检查方法不能被一个接口实例继承
因为不是定义在接口构造器内,也不是通过Interface.prototype来定义的
*/
Interface.ensureImplements = function(object)
{
if(arguments.length < 2) { throw new Error("至少需要2个参数"); }

//第一个参数object是类,第二个开始时类所要实现的接口
for(var i = 1, len = arguments.length; i < len; i++) 
{
var interface = arguments[i];
if(interface.constructor !== Interface)
{ throw new Error("该接口不是由接口声明函数Interface构造的"); }

for(var j = 0,methodsLen=interface.methods.length;j<methodsLen;j++)
{
var method = interface.methods[j];
if(object[method]=="undefined" || typeof object[method] !== 'function') 
{
throw new Error("接口检查: object 没有实现接口 " + interface.name + "名为" +method+ " 的方法");
}
} //end for j
} // end for i
}
 
5.使用接口构造器构造接口和检查对象是否实现了接口
var interface_1 = new Interface('interface_1', ['add', 'remove', 'getChild']);
var interface_2 = new Interface('interface_2', ['getValue']);

function Aclass(){
this.interfaces = ["interface_1","interface_2"];//该类自称实现了2个接口
this.method_1=function(){}
this.method_2=function(){}
this.add=function(){} 
this.remove=function(){}
this.getChild=function(){}
}
var myClass = new Aclass();
//使用myClass是可以检查识别它实现的接口: myClass.interfaces
//严格检查myClass是否真的实现了interface_1接口和interface_2接口
Interface.ensureImplements(myClass, interface_1, interface_2);
 
6.接口检查或多或少都会影响性能, 接口 检查 可以在开发中启用,在发布时关闭
使用程序之前引入一个配置文件:Conf.js,该文件在window对象下建立一个命名空间,并把一些配置参数写在该命名控件下。
Conf.js 内容:
CONF={ debugMod:true, ... }

根据 debugMod来决定是否检查接口:
if(CONF.debugMod){
Interface.ensureImplements(myClass, interface_1, interface_2);
}
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值