JavaScript中并没有内置的创建或实现接口的方法。这里将利用JavaScript的灵活性,来实现与接口意义相同的功能。

什么是接口?

接口的好处:

  • 接口提供了一种用以说明一个对象应该具有哪些方法的手段。
  • 接口表明方法的语义,但并不规定这些方法应该如何实现。
  • 有了接口,就可以按对象提供的特性对它们进行分级。

面向对象的JavaScript中接口的作用:

  • 既定的一批接口具有自我描述性,并能促进代码的重用。
  • 接口可以帮助对类的使用。
  • 接口有助于稳定不同的类之间的通信方式。

JavaScript中接口的弊端:

  • 接口在一定程度上强化类型的作用,从而降低的JavaScript弱类型的特性。
  • JavaScript用模仿的方式实现接口的特性,这有一定的风险。
  • JavaScript中,实现接口的方法都会对性能造成一定的影响,在某种程序上这是因为额外的方法调用的开销。
  • JavaScript中,无法强制程序员遵守你定义的接口。

在JavaScript中模仿接口

1. 用注释描述接口

    /*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
}
*/

使用注释来描述接口,很难对接口的实例进行控制。

2. 用属性模仿接口

使用特定的方法来对特定的对象进行检查,看其是否实现了一组对应的方法,从而判断是否符合接口的要求。

使用属性模仿接口,主要是在实例声明的地方使用一个数组对象作为实现的接口的描述。然后在使用这个实例的时候,再使用一个存储接口名称的数组对象对其进行一个检查,看是否实现了相应的接口。

这里要注意的是,implementsInterfaces是一个接口保称的数组,arguments的遍历是从1开始,而不是从0开始,因为arguments[0]是传入的待判断对象。

function implements(object) {
for (var i = 1; i < arguments.length; i++) {
var interfaceName = arguments[i];
var interfaceFound = false; for (var j = 0; j < object.implementsInterfaces.length; j++) {
if (object.implementsInterfaces[j] == interfaceName) {
interfaceFound = true;
break;
}
}
if (!intefaceFound) {
return false;
}
}
return true;
} var CompositeForm = function(id, method, action) {
this.implementsInterfaces = ['Composite'];
// ...
};
function addForm(formInstance){
if(implements(formInstance,'composite')){
throw new Error(Object does not implement a required interface.);
}
// ...
}

这种方法,对类所实现的接口提供了文档说明,如果实例没有实现接口,就会得到一个错误。

但是,这种方法从根本上说,并未确保类真正实现了自称实现的接口。

3. 用鸭式辨型模仿接口

像鸭子一样走路并且嘎嘎叫的就是鸭子。

主要观点:如果对象具有与接口定义的方法同名的所有方法,那么就可以认为它实现了这个接口。

使用这种方法需要一个辅助函数来对实现接口的方法进行判断,看某个对象是否实现了某个接口。

推荐的模仿接口的方法

我们可以使用一个辅助类Interface及其类方法Interface.ensureImplements来对对象实现的方法进行显式检查。

var Interface = function(name, methods) {
if (arguments.length != 2) {
throw new Error("Interface constructor called with " + arguments.length +
"arguments, but excepted exactly 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 constructor expects method names to be passed in as a string.");
}
this.methods.push(methods[i]);
}
}; Interface.ensureImplements = function(object) {
if (arguments.length < 2) {
throw new Error("Function Interface.ensureImplements expects " +
"arguments two and above to be instances of Interface.");
} for (var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
var method = interface.methods[j]; if (!object[method] || typeof object[method] !== 'function') {
throw new Error("Function Interface.ensureImplements: object does not implement the " +
interface.name + "interface. Method" + method + "was not found.");
}
}
}

在使用这种方法的时候,我们可以使用Interface作为类型,然后将接口名称以及接口的方法以参数列表的形势传入。然后再在调用这个接口的实例的时候,调用ensureImplements方法进行判断是否实现了这一个接口。

这里我们使用typeof object[method] !== 'function'检查对象是否包含某个方法。

var ResultSet = new Interface('ResultSet',['getDate','getResults']);
var ResultFormatter = function(resultsObject){
Interface.ensureImplements(resultsObject, ResultSet);
this.resultsObject = resultsObject;
};
ResultFormatter.prototype.rederResults = function(){
// ...
};

『JavaScript』模仿接口的更多相关文章

  1. 『JavaScript』核心

    弱类型语言 JavaScript是一种弱类型的语言.变量可以根据所赋的值改变类型.原始类型之间也可以进行类型转换.其弱类型的物质为其带来了极大的灵活性. 注意:原始类型使用值传递,复合类型使用引用传递 ...

  2. 『Java』Collection接口 Collections类

    接口Collection public interface Collection<E>定义了所有单列集合中共性的方法,所有的单列集合都可以使用共性方法. Collection的常用子接口有 ...

  3. 『JavaScript』new关键字

    原文 new关键字做了什么 在JavaScript中,使用new关键字后,意味着做了如下四件事情: 创建一个新的对象,这个对象的类型是object: 设置这个新的对象的内部.可访问性和[[protot ...

  4. 『JavaScript』封装

    封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏.通过封装可以强制实施信息隐藏. 在JavaScript中,并没有显示的声明私有成员的关键字等.所以要想实现封装/信息隐藏就需要从另外的思路出 ...

  5. 【总结】浅谈JavaScript中的接口

    一.什么是接口 接口是面向对象JavaScript程序员的工具箱中最有用的工具之一.在设计模式中提出的可重用的面向对象设计的原则之一就是“针对接口编程而不是实现编程”,即我们所说的面向接口编程,这个概 ...

  6. 『WPF』DataGrid的使用

    原文 『WPF』DataGrid的使用 几点说明 这里主要是参考了MSDN中关于DataGrid的说明 这里只会简单说明在WPF中,DataGird最简单的使用方法 对于MSDN中的翻译不会很详细,也 ...

  7. 『TensorFlow』专题汇总

    TensorFlow:官方文档 TensorFlow:项目地址 本篇列出文章对于全零新手不太合适,可以尝试TensorFlow入门系列博客,搭配其他资料进行学习. Keras使用tf.Session训 ...

  8. 『TensorFlow』批处理类

    『教程』Batch Normalization 层介绍 基础知识 下面有莫凡的对于批处理的解释: fc_mean,fc_var = tf.nn.moments( Wx_plus_b, axes=[0] ...

  9. 『计算机视觉』Mask-RCNN_从服装关键点检测看KeyPoints分支

    下图Github地址:Mask_RCNN       Mask_RCNN_KeyPoints『计算机视觉』Mask-RCNN_论文学习『计算机视觉』Mask-RCNN_项目文档翻译『计算机视觉』Mas ...

随机推荐

  1. 【[USACO15FEB]审查(黄金)Censoring (Gold)】

    从原来的单串匹配变成了多串匹配 好像也没什么特别不一样的地方 原来的做法是搞一个栈,之后一旦匹配到就往前弹栈 做法也一样 但是在\(AC\)自动机上暴力跳\(fail\)是要\(T\)的 我们并没有必 ...

  2. PHP面试题分享与答案

    由于之前的每一个问题都是一个比较大的知识点,作者希望可以尽量一一详细解答,如果有不足的地方欢迎大家补充和修改,同时借鉴牛人写的Mysql中算法的实现以及内存原理,Btree结构等. 1:MySQL数据 ...

  3. Visual Studio 2010 RDLC 报表简单使用

    原文:Visual Studio 2010 RDLC 报表简单使用 RDLC(Report Definition Language Client-side Processing)是Visual Stu ...

  4. 【luogu P3378 堆】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3378 是堆的模板...我懒,STL da fa is good #include <iostream& ...

  5. Android学习笔记_29_样式和主题

    一.简单样式定义和使用: android中的样式和CSS样式作用相似,都是用于为界面元素定义显示风格,它是一个包含一个或者多个view控件属性的集合.如:需要定义字体的颜色和大小. 在Android中 ...

  6. HDU 1110 Equipment Box (判断一个大矩形里面能不能放小矩形)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1110 Equipment Box Time Limit: 2000/1000 MS (Java/Oth ...

  7. sql server 语句获取表的描述,主键等等

    sql语句添加表,字段的描述 --添加表的描述 --格式如右:execute sp_addextendedproperty 'MS_Description','字段备注信息','user','dbo' ...

  8. LeetCode3.无重复字符的最长子串 JavaScript

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...

  9. H5新增API和操作DOM

    博客原文:https://dobinspark.com.cn/ H5-dom扩展 获取元素 document.getElementsByClassName ('class'); //通过类名获取元素, ...

  10. watch、computed、methods的区别

    1. `computed`属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算.主要当作属性来使用,要return出去一个值:2. `methods`方法表示一个具体的操作,主要书写业务逻辑:3. ...