在JS中接口是面向对象最有用的工具之一,它可以提供一种说明一个对象应该具有哪些方法的手段。但是在JS中并没有接口的说明关键字interface,也没有用以实现接口的implements ,这个同前面的继承相似,只能通过模仿来描述接口。
1. 注解描述法
这种方式是通过注释的方式给出接口的描述,特点如下:
优点:对于开发的人可以有个参考
缺点:这个是属于文档的形式的,太过于松散,并没有检查接口的方法是否实现
具体的例子如下:
/*
* interface composite{
function add(obj);
function remove(obj);
function update(obj);
}
*/
//compositeImpl implements Composite
function compositeImpl(){
}
compositeImpl.prototype.add = function(obj){};
compositeImpl.prototype.remove = function(obj){};
compositeImpl.prototype.update = function(obj){};
var c1 = new compositeImpl();
var c2 = new compositeImpl();
c1.add(7);
c2.add(9);
//函数里用var定义的变量是局部变量,对于实例来说是相等的
alert(c1.add === c2.add);
2. 属性检测法
显式的在类的内部,接受所实现的接口,这种方法需要在类的内部定义一个数组,但这种方法只能确定在implementsIns 中,是否包含要实现的接口,并不能确定该“接口”的方法是否被实现,总之,这种方法还是寄托于程序员的高素养。
具体的例子如下:
/*
interface Composite{
function add(obj);
function remove(obj);
fucntion update(obj);
}
interface FormItem{
function select(obj);
}
*/
//CompositeImpl implements composite
var compositeImpl = function(){
this.implementsIns = ['Composite', 'FormItem'];
};
compositeImpl.prototype.add = function(){
alert('add');
};
compositeImpl.prototype.rmeove = function(){
alert('remove');
};
compositeImpl.prototype.update = function(){
alert('update');
};
compositeImpl.prototype.select = function(){
alert('select');
};
function checkCompositeImpl(instance){
if(!checkImplement(instance, 'Composite', 'FormItem')){
throw new Error('interface do not implements');
}
}
function checkImplement(obj){
for(var i = 1, len = arguments.length; i < len; i++){
var intName = arguments[i];
var result = false;
var ary = arguments[0].implementsIns;
for(var j = 0, size = ary.length; j < size; j++){
if(ary[j] == intName){
result = true;
break;
}
}
}
return result;
}
var c1 = new compositeImpl();
checkCompositeImpl(c1);
c1.add();
3. 鸭式变型法
这种方法就可以确定在实现“接口”的过程中是否实现了该接口的方法,相比较于前两种方法,这种方式还是比较常用的
具体的例子如下:
function Interface(name, methods){ //记录一个接口有的抽象方法
if(arguments.length != 2){
throw new Error('arguments length must >= 2');
}
this.name = name;
this.methods = [];
for(var i = 0, len = methods.length; i < len; i++){
if(typeof methods[i] !== 'string'){
throw new Error('Interface methods should be string array');
}
this.methods.push(methods[i]);
}
}
var compositeInterface = new Interface('compositeInterface', ['add', 'remove']);
var formItemInterface = new Interface('formItemInterface', ['select']);
var CompositeImpl = function(){
};
CompositeImpl.prototype.add = function(){
alert('add');
};
CompositeImpl.prototype.remove = function(){
alert('remove');
};
CompositeImpl.prototype.select = function(){
};
//确定实现接口的种类及它的方法是否实现
Interface.ensurePlements = function(instance, interfaceIns){
if(arguments.length < 2){
throw new Error('arguments should contains interfaceIns');
}
for(var k = 1, len = arguments.length; k < len; k++){
var interfaceName = arguments[k];
if(interfaceName.constructor !== Interface){
throw new Error('interfaceIIns constructor must be Interface');
}
for(var j = 0, length = interfaceName.methods.length; j < length; j++){
var method = interfaceName.methods[j];
if(!instance[method] || typeof instance[method] !== 'function'){
throw new Error('instance must implements method ' + method);
}
}
}
}
var c1 = new CompositeImpl();
Interface.ensurePlements(c1, compositeInterface, formItemInterface);
c1.add();
Tip:
JS中的接口在设计模式中应用中还是比较广泛的,关于设计模式,在之后的博文中会进行说明,欢迎关注